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:
- 55% for Part A
- 35% for Part B
- 10% for getting Parts A & B to work together
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?
- 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.
- 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.
- 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.
- 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.
- 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.
- If it finds a password pass, it should print 'Found:
pass'
- If it does not find a password, it should print 'Not Found'
- 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?
- 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.
- 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.
- 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.
- 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:
- In the lsp subdirectory, compile your code with the command
gomake contrib
- In the echoclient subdirectory, edit the import portion of the file
echoclient.go, as described in the file
- 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.