/TCP-Cloning-Protocol-Daemon

An exercise in implementing TCP-like features on top of UDP

Primary LanguageC++

ftpc and ftps are a pair of applications that work to simply transfer files between two IP hosts.
tcpdaemon is a daemon that implements some features of TCP on top of UDP at the application layer.


You can compile the client, server, and the tcpdaemon by issuing a "make". The binaries are placed in the "bin" directory
You MUST be using GNU make, so if you are on a non-Linux Unix(e.g. Solaris) you must use gmake.


To use, first run the troll application on a host and specify a port number
Then, run tcpdaemon on both endpoints. On each one, you must specify on the command line the host and then the port where the troll application is running. e.g. "./bin/tcpdaemon 127.0.0.1 5678"

Then, run ftps on the machine meant to receive the file.  ftps takes one argument, the port(UDP) on which to listen.
e.g. "./bin/ftps 5566"

Next, run ftpc on the host sending the file. ftpc requires 3 arguments.
The first argument is the host on which to connect(the host that is running ftps).
The second argument is the port number on which to connect to ftps(the same port number specified on the ftps command)
The third argument is the name of a file to send.
e.g. "./bin/ftpc ahost 5566 afile.txt"

ftpc will send the file to ftps. Both applications and the daemon will print out various information about the process that you can safely ignore.

Notice, you can transfer files with any length filename, but the filename of any file whos name exceeds 20 characters will be truncated.
Example Usage:

[machinea]./troll-linux  -x 0 -t -s 0 $TROLLPORT
[machineb] ./tcpdaemon machinea $TROLLPORT
[machineb] ./ftps $SERVERPORT 
[machineb] ./ftps machineb $SERVERPORT afilename 

The daemon is designed to implement the full interface of the POSIX TCP socket layer.

TCP Features:

TWO-WAY-HANDSHAKE:
The TCP twoway handshake is implemented. When a client connects, it sends a SYN packet and the receiving end responds with a SYNACK

CUMULATIVE ACK:
Cumulative acks are implemented. This means that if a number of ACKS are lost or corrupted, the next ACK to arrive ACK's all previous packets.

MULTIPLE CLIENTS:
TCPDaemon can provide service for any number of services running on the local machine to any number of destinations. 

CYClIC REDUNDANCY CHECK (CRC):
This implementation of tcp uses a cyclic redundancy check to insure data integrity. The implemented crc uses a 32 bit polynomial to generate a 32 bit code. The crc is computed in reverse of normal crc implementations in that the lowest data bit is used to determine the divide. A table of all of the potential 8 bit crc's is computed before hand using each ascii character. This allows for the entire erc to be computed byte by byte or character by character rather than bit by bit.

FILES:

client.cpp: The ftpc binary
server.cpp: The ftps binary
tcpmain.cpp: The main() for the tcpdaemon binary
common.h: Various constants used by all binaries for the IPC comm system
tcpdaemon/api.(h|cpp): The IPC client. This is linked into ftpc and ftps. It contains the implementation for SOCKET(),BIND(),CONNECT(),LISTEN() etc etc
tcpdaemon/TCPDaemon.(h|cpp): The primary TCPDaemon object. This object poll()s on relevant sockets,creates TCPConn objects, alerts TCPConn objects when data is arriving.
tcpdaemon/TCPConn.(h|cpp): The TCPConn object encapsulates all information about a "connection". Each end has a corresponding TCPConn object. They are created when a BindRequest or ConnectRequest packet is sent by a client application
tcpdaemon/packets/IPCPackets.(h|cpp): Contains implementation for all IPCPackets sent between a client and TCPDaemon over domain sockets. Packets sent by a client to the daemon are "Request" packets, and the client blocks until a corressponding "Response" packet is received from the Daemon.
tcpdaemon/packets/TCPPackets.(h|cpp): Contains implementation for all TCPPackets sent between TCPDaemons. It encapsulates writing and receiving data on the wire and computing and checking the checksum
tcpdaemon/Timers/TimerService.(h|cpp): Contains implementation for the TimerService and DeltaTimers. DeltaTimers are registered with the TimerService when a packet is sent from a TCPConn. TCPDaemon actually times the timeout with poll() and alerts the TimerService who, in turn, alerts the associated TCPConn

KNOWN ISSUES:
Connections are not correctly closed and cleaned up, i.e. there is no TIME_WAIT step. This means that if the receiving end receives the last data that it wants, but the ACK is lost, the initiating end will continue to repeatedly send the last packet forever.

Currently the sockaddr_in header rewritten by the troll is not correctly checksummed. This means that if the sockaddr_in is garbled in transit, the other end will not know. 

Currently, two TCPDaemons on two different machines are not properly communicating due to errors in the checksum logic.

While the final intent is to implement the full socket API, the daemon has only been tested for one way communication using a CONNECT() to a corresponding ACCEPT() and pairs of SEND() and RECV(). Full duplex communication may work, but has not been tested. A listening server is also not able to ACCEPT on multiple connections.