The aim of this project is to implement three fundamental parts of the transmission control protocol, TCP,
Most of the functionality in the previous projects is portable into this project but there is a difference in answer generation. The direct decode-answer chain in project 3 will be replaced by the more abstract mechanism of an answer-chain in this project. The answer-chain implies changes in the IP, LLC, and ethernet layers in order to correspond to the implementation in the TCP layer.
There is some administration in order to obtain the source code. Refer to the suggested design of the class hierarchy as well as advice on how to approach the completion of the skeleton code. An executable which may be loaded into the ETRAX unit is compiled, linked, and loaded in the same manner as in the previous overview of the system. Finally, you will have to test your solution.
Read chapters 17, TCP, 18, TCP connection establishment and termination, and 19, TCP interactive data flow in [Stevens96]. An understanding of the state machine and the state transition diagrams in pp.241-242 is fundamental in order to complete this project successfully.
Consult RFC793 on TCP.
The stream concept is the key in order to understand sequence and acknowledgement numbers in TCP. All data are treated as a stream of bytes. Thus, each byte is tagged by a sequence number and the concept of a packet does not apply to TCP. Instead, the concept of a segment is used which is a subset of the total stream of bytes. Every segment contains the sequence number of the first byte in the segment. The acknowledgement number is transmitted from the receiver of a segment and corresponds to the next sequence number the receiver expects to receive.
In addition to the stream, there are a number
of flags in the TCP header. Each segment transmitted may imply an
action or a state transition in the TCP state machine by setting
certain flags. A few flags are also intended to be received by an
application which uses the TCP connection. One or several flags
may be turned on in each TCP header. The bit correspondence to
the flags in the field of the header are
URG | ACK | PSH | RST | SYN | FIN |
5 | 4 | 3 | 2 | 1 | 0 |
The example below of connection establishment,
data transfer, and connection termination shows that both the SYN
and FIN flags must have a sequence number although the segments
do not contain data. An ACK flag is sent with the SYN and FIN
flags except in the very first SYN segment since there is
no overhead involved in adding it.
Port numbers, [Stevens96] p.12, are an
important concept in TCP. A connection is defined by port numbers
together with IP addresses. In the figure, two clients have three
different active HTTP connections. All connections are with
respect to the server port number 80, the HTTP port. In addition,
two of the connections are from the same IP address. However,
since a running port number is allocated on the client side, each
new session is uniquely defined by four parameters, the client IP
address and the client port number together with the server IP
address and the server port number.
Connection | Client IP address | Client port number | Server IP address | Server port number |
1 | 194.47.61.9 | 2614 | 194.47.61.91 | 80 |
2 | 194.47.61.9 | 2615 | 194.47.61.91 | 80 |
3 | 194.47.61.14 | 3011 | 194.47.61.91 | 80 |
The telnet protocol is the base in almost all applications utilising the TCP stack. Both FTP, file transfer protocol, SMTP, simple mail transfer protocol, and HTTP, hypertext transfer protocol, have the telnet protocol as a base. In principle, telnet provides a raw data channel between two computers where characters are transmitted without interpretation. The applications use the raw data channel in order to send commands formatted as text strings terminated with the ASCII sequence CR, carriage return, and LF, line feed. It is the responsibility of the applications to accomplish the interpretation of the commands. For example, a log in sequence in FTP might look like
The commands USER and PASS are exchanged between the ftp
applications in this example.
The telnet application may connect to other ports than the
default port 23, which is the telnet port. The port number
entered at the end of a telnet command becomes the port number
the application tries to connect to. For example, the command telnet www.eit.lth.se 80 followed by the
command GET /index.html provides
an excersise in reading HTML code.
E-mail is sent by the SMTP protocol in the same manner. Thus, it is possible to be one owns mail server and send fake mail by the telnet application.
In principle, there are four packets, logical units, in the design pattern below
The class TCP is provided with all the functionality required in this project. The only remaining design issue to be addressed is where and when it should be instantiated.
The remaining three packets are coupled. Each TCPInPacket instance is associated with one TCPConnection and one TCPSender. When the underlying IP layer creates a new instance of TCPInPacket and tells it to decode itself, it
A new connection instance of TCPConnection creates a TCPSender and enters the initial state of the TCP state diagram. The TCPSender instance, in turn, has created a copy chain of all lower lying instances, stored in the reference myAnswerChain. It is essential to understand the reply mechanism in the individual states of the TCP state machine where a call of e.g. theConnection->myTCPSender->sendFlags(0x01) finally results in a call of myAnswerChain->answer(...) in the instance of the TCPSender.
Another essential design issue is the state machine. Each action or state transition within the TCPConnection instance actually implies the corresponding action or state transition in the present state of the connection. Thus, one action may have different effects depending on the state of the connection. The implemented design is referred to as a state pattern and at this point it might be necessary to consult the TCP state diagram.
A code example of how a received synchronise segment with the SYN flag set is handled will show how the different instances interact. The code may be used as it is presented in the solution. The files tcp.[hh,cc] contain the design framework.
The class TCPSender implements two methods
The previous design where each packet received was acknowledged with a reply does not apply to a TCP connection since its life time is for a longer period. Instead, a design is required where several segments may be sent which are unrelated to any received segment. Thus, all information about the established connection must be remembered by the TCPSender instance.
The proposed solution in this project is to create a chain of all layers in the initial ethernet frame received when the connection is established. The variable myAnswerChain in the TCPSender will be a reference to the IP layer which is responsible for the creation of the TCPInPacket instance. In practice, the class TCPInPacket contains the method
InPacket*
TCPInPacket::copyAnswerChain()
{
return myFrame->copyAnswerChain();
}
which returns the method copyAnswerChain() in the IPInPacket class, and this is what myAnswerChain in the TCPSender is a reference to. Thus, the new design requires a method called copyAnswerChain() in each layer which must be declared and implemented. Start by adding the declaration
InPacket* copyAnswerChain();
in the public section of the classes IPInPacket (ip.hh), LLCInPacket (llc.hh), and EthernetInPacket (ethernet.hh). Continue with the implementation in the IP layer (ip.cc)
InPacket*
IPInPacket::copyAnswerChain()
{
IPInPacket* anAnswerPacket = new IPInPacket(*this);
anAnswerPacket->setNewFrame(myFrame->copyAnswerChain());
return anAnswerPacket;
}
and the link layer (llc.cc)
InPacket*
LLCInPacket::copyAnswerChain()
{
LLCInPacket* anAnswerPacket = new LLCInPacket(*this);
anAnswerPacket->setNewFrame(myFrame->copyAnswerChain());
return anAnswerPacket;
}
and finally in the ethernet layer (ethernet.cc)
InPacket*
EthernetInPacket::copyAnswerChain()
{
EthernetInPacket* anAnswerPacket = new EthernetInPacket(*this);
anAnswerPacket->setNewFrame(NULL);
return anAnswerPacket;
}
The checksum for each TCP segment to be transmitted must be
calculated. A pseudo header is added to the ordinary TCP header
in the checksum calculation. The description in [Stevens96] in
p.144 and p.227 is not detailed enough, whereas RFC793
provides all the necessary information with respect to the pseudo
header.
Source IP address (32 bit) | ||||
Destination IP address (32 bit) | ||||
0x00 (8 bit) | Protocol (8 bit) | Total length (16 bit) |
The protocol field is set to the protocol number of TCP. The total length field must be set to the TCP header length plus the data length in byte, and it does not count the 12 byte of the pseudo header.
The PSH and ACK flags must always be set in a TCP segment to be transmitted containing data.
A check of memory leaks (dynamically allocated memory not returned to the system) may be accomplished by a printout in the frontpanel class for example. Every time a LED blinks the total amount of memory left in the system may be printed with the statement
cout << "Core " << ax_coreleft_total() << endl;
Remember, all protocols in TCP/IP are big endian whereas the ETRAX architecture is little endian. Thus, the opposite ordering of bytes in integers are used. The macro HILO solves the translation between the two endian formats. For example,
// 16 bit integers
uword realPacketLength = HILO(anIPHeader->totalLength);
anIPHeader->totalLength = HILO(realPacketLength);
Only 16 bit integers are affected since integers only are interpreted in the sense of big or little endian. Other fields, e.g. the IP address and the ethernet address, are interpreted without being affected by the endian. The corresponding macro handling 32 bit integers is called LHILO. For example,
// 32 bit integers
udword sequence = LHILO(aTCPHeader->sequenceNumber);
No rule without an exception. The function calculateChecksum returns a result which is big endian, according to the network byte order, and should not be altered.
aTCPHeader->checksum =
calculateChecksum((byte*)aTCPHeader,
totalSegmentLength,
pseudosum);
Make sure your present working directory is ~/kurs/src. Remove the subfolder lab4 if it exists in ~/kurs/src. Copy all files from your solution in project 3 with the command
cp -r lab3 lab4
and change your present working directory into ~/kurs/src/lab4. This project will be an extension of your solution in project 3. Add the skeleton of project 4 to your previous files with the command
cp -r ~inin/kurs/src/lab4/* .
There should be two files in addition to the ones from project 3 in the directory lab4,
The target of the make process is defined in the file /kurs/make/lab4/modules. Make sure your present working directory is ~/kurs/make and type the commands:
The tools in this project are
The telnet program is used in order to verify the solution
telnet <ETRAX IP-address> 7
where 7 corresponds to the ECHO port number.