[HW 1] TCP Proxy

Introduction

The first programming project is meant to introduce you to socket programming, as well as the Unix software development environment (gcc, make, etc.). You may find it useful to refer to this document for socket programming (Beej's Guide to Network Programming).

Your task will be to write a TCP Proxy. You'll learn how to write both client and server code in this homework.

A TCP proxy server is a server that acts as an intermediary between a client and another server, called the destination server. Clients establish connections to the TCP proxy server, which then establishes a connection to the destination server. The proxy server sends data received from the client to the destination server and forwards data received from the destination server to the client. Interestingly, the TCP proxy server is actually both a server and a client. It is a server to its client and a client to its destination server.

The assignment

The proxy server you will build for this homework will be invoked at the command line as follows:

# ./tcp_proxy destination-host destination-port listen-port

For example, to redirect all connections to port 3000 on your local machine to yahoo's web server, run:

# ./tcp_proxy www.yahoo.com 80 3000 

HW 1

The proxy server will accept a single connection from a client and forward it using a single connection to the server. During the connection, the proxy will not accept any other connections.

Specifications

The proxy must behave as followings: Lastly, you must carefully handle memory operations. There must be no memory leaks, dangling pointers, buffer overflows, and any vulnerabilities that C might introduce. Any bug related to memory operations will be counted negatively to your credit.

Fetching and building the source

Start by downloading the skeletal code from CMS (tcp_proxy.tar.gz), then copy it (using scp/rsync) to your home directory on one of your Fractus instances. You may use the same image you created during Lab 0. You should be able to get the files from your local box to your instance and build like this:
prompt> scp -i ~/.euca/id-rsa-kp-vs442-test tcp_proxy.tar.gz ubuntu@XX.XX.XX.XX:~/
prompt> ssh -i ~/.euca/id-rsa-kp-vs442-test ubuntu@XX.XX.XX.XX
# tar -xzf tcp_proxy.tar.gz
# cd tcp_proxy
# make
gcc -pthread -o tcp_proxy tcp_proxy.c 
First, make sure that you save your work before terminating your instance, either by placing it in a bucket, using a version control system like (CVS, SVN, Git, darcs, etc.), or simply fetching it back on your machine. To fetch it back on your machine, follow the steps:
# cd .. (come outside the dir tcp_proxy)
# tar -czf tcp_proxy.tar.gz tcp_proxy --exclude=".git"
prompt> scp -i ~/.euca/id-rsa-kp-vs442-test ubuntu@XX.XX.XX.XX:tcp_proxy.tar.gz . 

Do not include any files associated with version control systems in your tar ball.

That's it! You've now built tcp_proxy. To test it, type, for example:
# ./tcp_proxy www.yahoo.com 80 1234 
Now you should test your program using telnet. In the new window, run:
# telnet localhost 1234
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Connection closed by foreign host.
# 
The message "Connected to localhost" says that your proxy accepted a TCP connection, but then immediately closed it, since the proxy is not fully implemented. You must finish implementing the proxy. You are free to use any basic C library, or you can design your own data structures. It is possible to complete the assignment without using any other external libraries or data structures.

Testing

You should test your proxy to make sure that it continues to forward data even when some connections aren't responding. Here's one test you should be able to pass.

First, run the proxy and point it at fireless.cs.cornell.edu's HTTP port:

# ./tcp_proxy fireless.cs.cornell.edu 80 1234
Now, in another window, use telnet to fetch /big through the proxy:
# telnet localhost 1234
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET /courses/2014fa/cs5413/labs/big
Watch the data go by for a while, then interrupt the output by typing ''control-] RETURN'', after which telnet should stop and print telnet>. Now check that the proxy hasn't been hung because telnet isn't reading data; suspend your telnet by typing ''z RETURN'', wait for 10 seconds, and fetch something else:
telnet> z

Suspended
# telnet localhost 1234
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET /courses/2014fa/cs5413/labs/small
You got it!
Connection closed by foreign host.
If you see "You got it!," your program passes the test.

How/What to hand in

TCP proxy

You should submit two things: You should also build the software distribution as follows:
# tar -czf tcp_proxy.tar.gz tcp_proxy --exclude=".git" 
To turn in your distribution, upload the tcp_proxy.tar.gz file on CMS.


Useful tips