Peer Peer Messaging System
Peer Peer Messaging System
Overview
1
The initial peer implementation code provided with this problem de-
scription sets up a server communication socket based on the UID of the
person using the client. The UID is stored in a text file named .p2prc or
can be specified on the command line by running “peer <UID>”. The peer
has a simple user interface providing three commands MESG, DISP, and
QUIT.
Using the MESG command and a UID, a peer can try to connect to a
copy of itself that is also running on ”localhost” (or IP address 127.0.0.1).
If the requested peer is executing, a connection is established and messages
can be exchanged. The current message is just a text string, and does not
represent the structure of the packets that should actually be exchanged
between the peers. The DISP command is used to display an incoming
message.
To complete this laboratory you need to extend the existing code to
implement the facilities and application protocols specified in the assignment
stages appropriate to your course. Each stage builds on top of previous
stages, so you can extend your code from a previous stage when moving
forward in the assignment. Stages should be created as separate source
code and executable files named peer1, peer2, etc. See section ?? for more
information about hand-in instructions. It is important that you follow these
instructions to pass the assignment!
The code is provided as a tar-ball. The contents is as follows:
p2p/
|-- code_lib/ : Contains library code (DO NOT MODIFY).
|-- ns_source/ : Nameserver source code.
|-- p2p_source/
| |-- base/ : Contains your peer source code.
| ‘-- copy/ : Copies of your compiled programs.
‘-- serv_test/ : Program to test the name server.
2
• If you have access to for example a Linux machine, you can easily
detect byte order bugs by running one “peer” on a SUN machine and
one “peer” on the Linux machine and have them communicate with
each other.
• Run your own local nameserver for easier debugging while coding.
Good Luck!
3
2 Project Stages
Stage 1: A Simple Message Protocol
In short:
To send a message to a given UID one types the keyword MESG followed
by the desired UID and an alphanumeric text message of up to N characters.
The UID must be delimited by spaces in both commands. Your program
need not parse commands for correct grammar, you can assume that all
commands are well formed.
Your program should extract the relevant data from a MESG command,
check that the UID specified is known to the peer, and pack and send the
text to the other peer (UID) according to the packet format in figure ??. I.e.,
you need to change the current implementation that only sends an ASCII
string to instead send a binary header in front of the message. Currently no
packet format is defined in the code, so you will be required to implement
this yourself.
The current command line implementation of the DISP command does
not require a UID, since only one other peer process can be connected to
4
another. You should extend the program to allow connections to many peers
simultaneously and implement a command PEER that prints the curerntly
connected peers (e.g., IP address, number of received messages, etc.). You
will also need to extend the message notification and buffering, and the DISP
command to allow buffering and display of messages according to UID.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Reserved | UID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Message |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
In your extended version of the program, when the UID is not known to the
peer it should attempt to create a socket connection to that UID peer on
“localhost” (127.0.0.1), setting up appropriate data structures to manage
such a communication. If a connection can be established the message can
then be sent using the defined packet format. If the connection is not possible
the user should be notified that the message could not be delivered.
The length of the message is specified in the packet so that the server will
know how many bytes to read from the stream to get the entire message.
The source UID is specified, as the recipient of a connection request will
not know the UID of the requestor. Consequently we need to have that
information in the packets so that the peer that accepts the connection can
make an entry in the list of UID’s with which it has a connection and can
exchange messages directly. The type field is not really needed at this point,
but will later be used to differentiate between protocol control packets and
the data packets containing message data.
5
When a message is received the peer should notify the user of the mes-
saging application that a message has arrived, and from which UID that
message has arrived. Messages should be buffered in a FIFO queue of mes-
sages until the user issues a DISP command to display the next waiting
message from the specified UID. Displaying a message should automatically
delete it from the queue.
To handle multiple peers and queueing of messages you can use linked
lists. Library code implementing simple linked list routines are provided in
code lib/. The linked list library is provided for your convenience. Note
though, that the library routines implementing the linked lists do not deal
with memory management, so make sure you free the memory allocated by
the data structures you have added to the list when you detatch them.
Testing
Test that your peer code can communicate properly with copies of itself
with different UID’s. You should test several copies and connect in differ-
ent orders to each of the copies by issuing MESG commands to different
destinations.
Test your assumptions about packet format by trying to exchange mes-
sages with peer implementations written by your classmates.
Questions
Answer the following questions related to the solution to stage 1 of the
laboratory exercise. Each question should be answered using no more than
250 words to explain your reasoning.
2. Is there a limit on the total number of other peers that you can com-
municate with?
6
Stage 2: Distributed Messaging and a Control Protocol
In short:
Extend the code from stage 1 (by copying peer1.c to a file called
peer2.c), so that it connects (via TCP) to a nameserver database. Ini-
tially you should connect to a copy of the nameserver running on your own
machine “localhost” and test that your peer application interacts correctly
with the server, and can properly register itself and do IP lookups for UID’s.
Consult the serv test code if you are unsure how to communicate with the
name server and need some practical examples of registration and query
messages.
The structure of the command protocol that we use to interact with the
nameserver is as follows.
When your peer is running correctly with a local nameserver you should
start to use the public nameserver that is running on rama.it.uu.se at port
6345. This will provide a central point where you can register your UID and
IP, and lookup the current UID’s of chat peers for your friend’s UID’s. The
command protocol grammar is defined below.
Modify the connection algorithm for a message to attempt a connection
on the current machine, and if that fails to use the control message protocol
described below to look up the host’s location (IP Address) for the required
peer (UID) on the centralised nameserver.
To access nameserver services your peer must connect to rama.it.uu.se
port number 6345 which operates as a default name lookup database. If
no valid IP can be retrieved report to the user that the UID cannot be
discovered and that the message is undeliverable.
To communicate with the name server we send a shorter packet type
which is used to convey commands between peers instead of messages. This
packet type is depicted in figure ?? and is pre-defined for you in globals.h
as the type nsr pkt.
7
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| UID (1) | UID (2) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| IP Address (1) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| IP Address (2) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Not all fields of the command packet are filled in for all packet types, since
it is a general purpose packet format. The fields are specified as follows:
Type: An integer describing the type of the message (defined in globals.h).
Reserved: Field reserved for future usage, sent as 0.
UID (1): User ID #1 (different meaning depending on the packet type).
UID (2): User ID #2 (different meaning depending on the packet type).
IP Address (1): An IP Address corresponding to UID (1).
IP Address (2): An IP Address corresponding to UID (2).
Don’t forget to modify your code to replace the code that always connects
to localhost with code that uses the IP address that you have stored in
your local UID lookup table.
Testing
Once again, test your peer code can communicate properly with copies of
itself with different UID’s on the same computer. Extend the tests to place
the peers on different computers and test the command protocol by looking
up UIDs on the central nameserver running on rama.it.uu.se.
Now try to exchange messages with peer implementations written by
your classmates.
Questions
Answer the following questions related to the solution to stage 2 of the
laboratory exercise. Each question should be answered using no more than
250 words to explain your reasoning.
8
2. Reflect on the peer discovery problem. How do you find peers in the
system you have built? How reliable is this solution, and how might
it be made more robust?
3. How can you find out what peer UIDs are in existence, and how can
you record the UIDs of friends between sessions of the peer? Outline
a possible approach.
9
Stage 3: A Broadcast UID Resolution Protocol (BURP)
In short:
This stage of the project replaces the primitive control message pro-
tocol of Stage 2 which queried directly connected hosts and the name-
server with a more sophisticated broadcast based UID discovery protocol.
The control protocol’s packet format (nsr pkt) can be found in the file
code lib/globals.h.
Extend the data structure that you have used to store UIDs to sockets.
Add a hostnameIP entry so that we know what computer the peer is running
on. This creates a more complete lookup database for UID information in
the peers.
LRQ packets need to be given a time to live (TTL) in hops and sent out
to all peers to whom we have a direct connection using a broadcast flood
method. These packets are forwarded until they die, while the originator
waits for a positive response packet (RSP) that contains the host IP ad-
dress required. If this technique fails (timeout on RSP packet) the host is
considered unreachable and message delivery failure is reported to the user.
You should not look up the host name in the nameserver tables. The
nameserver is only to be used at startup to create a connection to two other
hosts which are chosen at random from the nameserver. To obtain two IP
addresses from the nameserver you should connect to it and send a packet
with the type field set to PRQ. The PRP packet that is sent in response
contains two IP addresses in the payload.
In solving this problem you should assume that a host that receives a
LRQ packet creates a direct TCP connection to the originator. It sends the
RSP packet over that link, and retains the link for further communication
with the originating peer. The peer that originated the LRQ packet can
use then use this connection to send the message to the required destination
UID.
Testing
As in stage 2 you should begin by testing that your peer code can commu-
nicate properly with copies of itself with different UID’s on several differ-
ent computers. Test the initial connection establishment algorithm using
a nameserver, either the central nameserver running on ”rama.it.uu.se”, or
one running locally.
10
A simple test scenario is to run four peers on different machines. Make
sure that two of them do not have connections to each other, but share one
of the other peers. It should now be possible to send a message between
the peers that do not have direct connection. After the BURP lookup, the
peers should have a direct connection between each other (check with your
PEER command). Now try to exchange messages with peer implementations
written by your classmates, you should also test their implementations of
the command protocol by asking them to broadcast lookups of UIDs for you.
Questions
Answer the following questions related to the solution to stage 3. Each
question should be answered using no more than 250 words to explain your
reasoning.
11
3 Hand-in Instructions
To pass the assignment you need to provide the complete source code for
the stages you are supposed to solve as well the answers to the questions.
It is important that you follow the steps below:
1. Your source tree should contain the files peer1.c, peer2.c, etc. cor-
responding to each of the stages that you have done. They should
automatically compile into their corresponding executable file by a
“make” from the top directory p2p/.
2. Create a tar ball with the complete source tree as shown in figure ??.
Name the tar ball “p2p-{username}.tar.gz”. Example:
4 Marking Guidelines
Laboratory results are allocated according to the following qualitative guide-
lines.
12
Peer to Peer Instant Messaging
Name(s):
Login Name:
Email:
Path to code:
(e.g., /home/gujo8932/p2p-gujo8932.tar.gz)
Date:
Signature: