Project Overview.
|
This project will introduce you to using the sockets API. Use whatever language you want but the course staff will be able to help you more with Java and Python. This project should be done by groups of 3. There are 2 parts to this project though you can start with either, especially if you are blocked on either part. |
Part 1 Overview.
|
In part 1 you will create a client application that will communicate with a server using a specific protocol. Your client's task is to follow the protocol as closely as possible and to extract a secret from the server for each stage of the protocol. The server's task is to validate that the client is following the protocol -- any deviation of the client from the protocol will cause the server to close the connection. The client and the server will communicate over UDP as well as TCP sockets. What follows is a thorough description of the protocol, broken up into stages (a,b,c,d). Remember, you must follow this protocol exactly. If you find any problems with this protocol description, or have further questions, do not hesitate to contact the TAs or the instructor. |
Protocol.
|
The server will run on the host on attu2.cs.washington.edu and attu3.cs.washington.edu, listening
for incoming packets on UDP port 12235. The server expects to
receive and will only send:
|
0 1 2 3 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | payload_len | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | psecret | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | step | last 3 digits of student # | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
The numbers at the top indicate the bit number in rows of 32 bits, and fields are separated by +- and | marks. The header is omitted from the following packet diagrams to eliminate redundancy, but remember that every packet has to have the header above. |
STAGE a: |
Step a1. The client sends a single UDP packet containing the string "hello world" without the quotation marks to attu2.cs.washington.edu (referred to as the 'server') on port 12235: |
0 1 2 3 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | hello world | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+Note: 'hello world' is not actually 4 bytes. |
Step a2. The server responds with a UDP packet containing four integers: num, len, udp_port, secretA: |
0 1 2 3 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | num | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | len | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | udp_port | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | secretA | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
STAGE b: |
Step b1. The client reliably transmits num UDP packets to the server on port udp_port. Each of these 'data' packets has length len+4 (remember that each packet's entire payload must be byte-aligned to a 4-byte boundary). The first 4-bytes of each data packet payload must be integer identifying the packet. The first packet should have this identifier set to 0, while the last packet should have its counter set to num-1. The rest of the payload bytes in the packet (len of them) must be 0s. The packet header length does not count towards len: |
0 1 2 3 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | packet_id | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | payload of length len | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
For each received data packet, the server will acknowledge (ack) that packet by replying with an 'ack' packet that contains as the payload the identifier of the acknowledged packet: |
0 1 2 3 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | acked_packet_id | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
To complete this step, the client must receive ack packets from the server for all num packets that it generates. To do so, the client resends those packets that the server does not acknowledge. The client should use a retransmission interval of at least .5 seconds. |
Step b2. Once the server receives all num packets, it sends a UDP packet containing two integers: a TCP port number, secretB. |
0 1 2 3 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | tcp_port | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | secretB | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
STAGE c: |
Step c1. The client opens a TCP connection to the server on port tcp_port received from the server in step b2. |
Step c2. The server sends three integers: num2, len2, secretC, and a character: c. |
0 1 2 3 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | num2 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | len2 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | secretC | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | c | +-+-+-+-+-+-+-+-+Note: If you receive 16 bytes as the payload_len, it's a mistake in our implementation so you can disregard that as it doesn't affect any of the later stages anyway. However don't make the same mistake in your part 2 stage c2. |
STAGE d: |
Step d1. The clients sends num2 payloads, each payload of length len2, and each payload containing all bytes set to the character c. |
0 1 2 3 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | payload of length len2 filled with char c | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
Step d2. The server responds with one integer payload: secretD: |
0 1 2 3 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | secretD | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
Part 2 Overview.
|
In part 2, you will be writing a web server that can handle clients communicating in a specific protocol. Your server's task is to verify whether the client adheres to the protocol and send a response only to the valid client. Your server should handle multiple clients at a time. |
Protocol.
|
We will follow the same protocol as part 1 and hence you can use
your client from part 1
to verify your server. The server should receive and send only:
|
0 1 2 3 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | payload_len | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | psecret | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | step | last 3 digits of student # | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
The numbers at the top indicate the bit number in rows of 32 bits, and fields are separated by +- and | marks. The header is omitted from the following packet diagrams to eliminate redundancy, but remember that every packet has to have the header above. |
Server:
STAGE a: |
Step a1. The client sends a single UDP packet containing the string "hello world" without the quotation marks to your server |
0 1 2 3 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | hello world | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+Note: 'hello world' is not actually 4 bytes. |
The server should verify the payload and respond with a UDP packet containing four integers: num, len, udp_port, secretA. All these numbers should be randomly generated.Then your server must wait for the client's packet at udp_port. |
0 1 2 3 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | num | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | len | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | udp_port | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | secretA | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
STAGE b: |
Step b1. The client will transmit num UDP packets in order to the
server on port udp_port. The server has to verify that
|
0 1 2 3 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | packet_id | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | payload of length len | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
For each received data packet, the server randomly decides whether to acknowledge (ack) that packet by replying with an 'ack' packet that contains as the payload the identifier of the acknowledged packet: |
0 1 2 3 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | acked_packet_id | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
The server should receive the same packet again if it decides to not send an ack.(Make sure your server does not send an ack atleast once for the entire transaction). This step will complete after the server receives num packets correctly in order. |
Step b2. Once the server receives all num packets, it should send a UDP packet containing two integers: a TCP port number, secretB. Now the server should wait for a TCP connection from the client at TCP port number. |
0 1 2 3 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | tcp_port | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | secretB | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
STAGE c: |
Step c1. The client will open a TCP connection to the server on port tcp_port received from your server in step b2. |
Step c2. Your server should then send three integers: num2, len2, secretC, and a character: c. |
0 1 2 3 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | num2 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | len2 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | secretC | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | c | +-+-+-+-+-+-+-+-+ |
STAGE d: |
Step d1. The clients sends num2 payloads, each payload of length len2, and each payload containing all bytes set to the character c. |
0 1 2 3 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | payload of length len2 filled with char c | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
Step d2. The server should respond with one integer payload: secretD: |
0 1 2 3 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | secretD | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
Due Date.
|
The project is due on October 27th at 11 PM. One submission per group. |
Programming details.
|
Your client and server program must compile from the terminal and run on the undergraduate server attu.cs.washington.edu or the UW CSE VM. If you code in Python, please specify which version of Python in the README. |
Turnin.
|
For part 1:
For part 2:
Please put each part in different folder (part1/ and part2/ under root would be fine) and collect all the materials in a single .zip file that includes all the necessary files, and hand it in on Gradescope. |
Grading.
|
Partial credit will be given for each of the completed stages of the
protocol for both parts of the project.
For part 1 the number of secrets that you were able to extract from the server is an indicator of your partial credit score. However, your code will be compiled and re-run against the server. If you were able to extract secrets from the server, your code must compile and be able to extract as many secrets as you have handed in with your assignment. For part 2 your code will be compiled and re-run with your client. |