15-440 Project 1 FAQ

The following web page is supplement to the main project document, available as a PDF .

How will points be allocated for the project?

We will divide the points for the project as follows:

What that means is that you are free to use our implementation of LSP when working on Part B, but you'll incur a slight penalty if you can't create a final version of the password cracker that runs on your implementation of LSP.

If we find bugs in our LSP code while working on Part B, can/should we fix them?

Yes. In doing the grading described above, we will consider both the LSP version you submitted with Part A, and the LSP version you submitted with Part B.

Part B

Is there any chance of extending the due date for Part B?

YES! We have delayed the initial due date for this assignment by 48 hours. It is now due Saturday, Oct. 1 at 10:00pm

How do I turn in my code for Part B?

  1. In the directory /afs/cs.cmu.edu/academic/class/15440-f11/P1/P1-B, you should find a subdirectory with the same name as your Andrew ID.
  2. Set up a complete working copy of your code in your directory. It can be a replica of what you've created in your version of P1-handout. If you have added any more packages, these should all be in separate subdirectories. There should be a subdirectories "request", "server", and "worker" containing compiled versions of your programs.
  3. You should have a Makefile in your directory that supports the commands "gomake clean" and "gomake all". The latter should compile your implementations of the server and the request and worker clients.

What's this about changes to the specification of the request client?

To facilitate automated testing, we require the following. This is a change from the description in the original writeup.
  1. The request client should be invoked as follows:

    ./request host:port hash len

    where host:port is the host and port number of the server, hash is the hash signature to be inverted, and len is the length of the password.

  2. The request client should print its results on standard output as follows. You must match this format precisely in order for our automated testers to work.
    1. If it finds a password pass, it should print 'Found: pass'
    2. If it does not find a password, it should print 'Not Found'
    3. If the client becomes disconnected from the server, it should print 'Disconnected'

What size passwords must our system be able to handle?

You should be able to handle passwords ranging in length from one character to six. The length is given as the third command-line argument to the request program.

Is any testing code available for Part B?

In the latest version of P1-handout.tar, subdirectory official contains automated testers for the request (rtest) and worker (wtest) clients. There is also an automated tester for the server (stest). See the documentation for rtest, wtest, and stest, as well as the README file for more information.

How should the server tell a worker to stop working on a job, e.g., because the password was found by another worker, or because the request client has died?

There is no mechanism to do this. Instead, the worker should just be allowed to complete its job and be given a new task when it responds. You should take this inability to kill a job into account when you select the maximum job size your server will use.

Part A

How do I turn in my code for Part A?

  1. In the directory /afs/cs.cmu.edu/academic/class/15440-f11/P1/P1-A, you should find a subdirectory with the same name as your Andrew ID. If you do not find such a directory, then please follow the procedure described in the next FAQ entry.
  2. Set up a complete working copy of your code in your directory. It can be a replica of what you've created in your version of P1-handout. If you have added any more packages, these should all be in separate subdirectories. There should be a subdirectory named "lsp" containing your lsp code + the two test files lsp_test.go and lsp_x_test.go.
  3. You should have a Makefile in your directory that supports the commands "gomake clean" and "gomake all". The latter should compile all of the code needed to test your version of LSP.
  4. We should be able to connect to your lsp subdirectory and run "gomake test," causing all of the tests we've provided to be run.

What if there is no handin directory for me?

Contact us ASAP at staff-440@cs.cmu.edu, and we'll set up one for you.

What if I can't submit my assignment via the instructions above?

Create a .tar file of your entire P1-handout directory, and email it to staff-440@cs.cmu.edu. We'll use the date of your email as the effective date of your handin.

Why can't I run gomake on an Andrew Linux machine?

Read the instructions in the assignment web page on how to get gomake onto your execution path.

How do I get the echo client or server to use my version of LSP, rather than the official solution?

You need to make sure to do all of the following:

  1. In the lsp subdirectory, compile your code with the command gomake contrib
  2. In the echoclient subdirectory, edit the import portion of the file echoclient.go, as described in the file
  3. In the echoclient subdirectory, type gomake clean and then gomake.
The corresponding procedure applies to the echo server. You will need to do steps 1 and 3 above every time you change lsp.go.

I can't find anything on the web about the Live Sequence Protocol. Is there an RFC?

As the writeup states, the protocol is ``home grown.'' It's intended to have the sort of features you might encounter in a real-world protocol, but many simplifications have been made to make it easier to implement.

The first data message from server to client has sequence number 1. Is the same true for the first message from client to server?

Yes. Separate series of sequence numbers are maintained in each direction.

Must a client or server wait until the end of an epoch to reply to a message, or can it respond immediately after processing?

It should reply right away. Here's one way to think about it: if UDP were perfect, then there would be no need for epoch events. LSP could simply be a request/acknowledge protocol, as illustrated in Figure 2. Epochs are layered on top of the request/acknowledge protocol to provide reliability.

If an LspClient waits more than K times delta between invocations to Read(), is the connection supposed to remain open?

The application client and server are totally oblivious to epochs, acknowledgments, and retransmissions. That's the job of the LSP implementation. The connection should remain open even if the client and server applications aren't doing any reading or writing.

Can connection ids or sequence numbers ever be negative?

Yes, in principle. Once the sequence number hits 2147483647, the next message will have sequence number -2147483648. But, if you assume a data rate of 1000 packets per second (far more than one would expect with the password cracker), it will take 24.8 days to hit this point. That's well past the due date for the assignment!

Seriously, this was a simplication we made. A more realistic protocol would use an unsigned number and would account for the possibility of roll over.

When I run the automated testing of my LSP implementation, it fails sometimes, but succeeds othertimes. Will I get marked as having an incorrect implementation?

The testing is not at all deterministic. There are random events, and it's being tested in real-world environment. We will test your code multiple times and call it a pass if it passes more often than not.

What are we supposed to do if the payload for a message is too big to fit into a UDP packet?

Nothing. You can assume that all messages will be small enough to fit into a single packet.

Does NewLspClient() block until it has received an ACK from the server acknowledging the connection?

No. It should return immediately. You'll want to use separate goroutines (threads) to manage the application client and to manage the UDP connection

Can we read and write on the same UDP socket with different threads?

Yes, the UDPConn functions are all thread safe.

I'm having trouble with JSON unmarshaling, here's my code:
n, cliaddr, _ := ServerConn.ReadFromUDP(buffer[0:])
p := new(Packet)
json.Unmarshal(buffer[0:], &p)

You need call Unmarshal with just the slice containing the actual data read. Replace the last line of your code with the following:
json.Unmarshal(buffer[0:n], &p)

When I read a packet, it comes back with size zero. What gives?

If you're certain the packet should have data, it's likely that you haven't allocated space to the buffer you're passing to the Read()/ReadFromUDP() function. You must have something backing it:

  var buffer [1500]byte
  ...
  <something>...Read...(buffer[0:])
Or you can allocate the buffer using make. But you can't just say
  var buffer []byte
because this has no associated storage into which Read can put data!

I'm getting weird results when I try to print information using fmt.Printf

That's because the functions in the fmt library are not thread safe. Try using the provided function Vlogf. It creates a Logger object (see the log package), which uses a mutex to ensure thread safety.