This assignment is intended to get you started with programming in the
Go language. To solve this assignment you will need to install Go,
figure out how to compile, run, and debug a Go program, and implement
a UDP+TCP-based protocols described below for connecting to two
services: a proof of work (PoW) authentication service, and a fortune
service. The assignment also has an extra credit component: your
solution will compete against other students' solutions in the total
time to retrieve and print out the fortune. The top fastest 10
solutions will receive an extra 2% added to their final course grade.
High-level protocol description
There are three kinds of nodes in the system: a client (that you will
implement), an authentication server (aserver) to verify a client's
submitted PoW, and a fortune server (fserver) that returns a fortune
string to the client. You will test and debug your solution against
running aserver and fserver instances. However, you will not have
access to their code. You are given initial starter code (below) which
contains the expected message type declarations. Both aserver and
fserver serve multiple clients simultaneously. Each client implements
a sequential protocol control flow, interacting with the aserver
first, and later with the fserver. The client communicates with
aserver over UDP and with the fserver over TCP using JSON messages.
The client is run knowing the UDP IP:port of the aserver. It follows
the following steps:
- The client sends a UDP message with arbitrary payload to the aserver.
- The client receives a NonceMessage reply containing
an string nonce
from the aserver and N, which determines the difficulty of
the PoW procedure.
- The client finds an string value of secret such
that the MD5 hash of
the concat(nonce, secret) value has N zeroes at the end of
the hash. The client then sends the secret value it found to
the aserver as part of a SecretMessage.
- The aserver verifies the client's PoW and replies with
a FortuneInfoMessage that contains information for contacting
the fserver (its TCP IP:port and an int64 fortune nonce to
use when connecting to it).
- The client sends a FortuneReqMessage to fserver.
- The client receives a
FortuneMessage from the fserver. This message contains a
fortune string as well as the rank of this solution
(relative to all other solutions that have correctly interacted with
the aserver and fserver).
- The client must print out the received fortune string on
a new newline-terminated line and then exit.
The communication steps in this protocol are illustrated in the
following space-time diagram:
Protocol corner-cases
- The aserver will reply with an ErrMessage in case the PoW
is invalid.
- The aserver will reply to all messages that it perceives as not
being SecretMessage with a new NonceMessage.
- The fserver will reply with an ErrMessage in case it
cannot unmarshal the message from the client.
- The fserver will reply with an ErrMessage in case an
incorrect fortune nonce is supplied in
the FortuneReqMessage.
- You can assume that all messages fit into 1024 bytes.
Implementation requirements
- The client code must be runnable on CS ugrad machines and be
compatible with Go version 1.9.2.
- Your code does not need to check or handle ErrMessage replies from
the aserver or fserver. However, you may find it useful to check for
these replies during debugging.
- Your code may assume that UDP is reliable and not implement any
retransmission.
- You must use the message types given out in the initial code.
- Your solution can only
use standard library Go
packages.
- Your solution code must be Gofmt'd
using gofmt.
Solution spec
Write a single go program called client.go that acts as a
client in the protocol described above. Your program must implement
the following command line usage:
go run client.go [local UDP ip:port] [local TCP ip:port] [aserver UDP ip:port]
- [local UDP ip:port] : local UDP address that the client uses
to connect to the aserver (i.e., the external
IP of the machine the client is running on)
- [local TCP ip:port] : local TCP address that the client uses
to connect to the fserver
- [aserver UDP ip:port] : the UDP address on which the aserver
receives new client connections
Starter code and testing servers
Download the starter code. The aserver is
running at IP:port 198.162.33.54:5555. The fserver is also
running.
Rough grading scheme
- 10% : Client properly initiates contact with the aserver
- 40% : Client computes a valid secret and communicates it to the aserver
- 25% : Client properly communicates to the fserver and provides the right fnonce
- 25% : Client prints out the right fortune message
Extra credit
The rank returned by the fserver gives you an idea of how fast your
solution is relative to other students in the course (who have tested
their solutions). In our extra credit testing we will use the same
nonce for all student solutions, and all solutions with a rank <= 10
will receive the extra credit of 2% added to their final course grade.
Make sure to follow the
course collaboration policy and refer
to the assignments instructions
that detail how to submit your solution.
|