Network Application Development 

4 阅读14分钟

Coursework 1 – Network Application Development Coursework Weight: 20%

In this coursework, you will develop several networking-based applications. These are designed to increase your competency in developing socket-based applications and increase your familiarity with several key technologies and measures. These are widely used and commonly deployed to evaluate networks and provide services.

During this practical, you will become familiar with network sockets and begin to understand how they are used. Sockets are a programming abstraction designed to assist us in building applications that use the network. We can treat these the same as any other resource; writing to a socket sends a packet into the network, whilst reading from a socket provides us with the contents of a packet. We can do this in much the same way as we would read and write to any file found on the local filesystem.

Practical Lab Structure

Practical 1 is split into two parts: Tasks 1 and 2. We also recommend that you complete the partially implemented Traceroute class before starting Task 1. For more, details, see Example Code 2 section on page 5.

For the tasks assessed, you will be awarded points for meeting certain criteria. These are outlined in more detail within each task description at the end of this document. You are encouraged to progress as far as possible with each task. However, note that Tasks 1 and 2 are independent; attempting both is advised, even if you do not fully complete each.

This course uses a dedicated virtual machine image for these labs.

Running the Code Locally

Running the code locally on your machine (directly and without a VM) is also possible. To do so, you will need to install Python 3 (version 3.10 or newer is recommended). As this task does not use any external libraries (see ‘Python Library Usage’ section below), this should be relatively easy to achieve.

Details on how to install Python can be found here: www.python.org/downloads/

There are some caveats with this approach, though (hence why we provide the virtual machine). Although the same Python code will run regardless of the environment, the underlying implementation (and therefore) behaviour can be different, including for many of the networkrelated libraries used in this practical. Particularly on the Windows platform (rather than MacOS or Linux), the results may be different.

Given the multitude of potential discrepancies and variances that may occur when running code locally, we will 代写Network Application Development  not provide direct support for the method; only the virtual machine-based approaches will be supported by the teaching team.

SCC. 231 Computer Networks and Systems 1

Practical 1 Network Application Development Michaelmas Term, 2024

Note that for marking, the provided virtual machine will (and must) be used. It is not an acceptable excuse to claim that it worked on your machine, so at the very least, please ensure that it runs on the provided virtual machine image (using one of the methods described in the sections below or above) before submitting.

Using the SCC 231 Virtual Machine

To access this, please use the following link and select the ‘SCC 231’.

mylab.lancaster.ac.uk/

The VM can be accessed via a browser or a downloadable client.

Provided/Skeleton Code

To help you structure your code and get started with each task, we have provided you with a skeleton code (NetworkApplications.py), which is available on the SCC.231 Moodle page. This file should eventually contain all the code you have developed in this lab and will be the one submitted at the end of your work. It contains a structure for the code, including some helper functions and empty classes. It also contains pseudocode for some of the tasks to get you started.

Firstly, there is a function included to parse command line arguments given to the script (setupArgumentParser). This includes determining which function is called (ping, traceroute, mtroute, web, proxy), as well as additional parameters used for each task. Some of these may be optional, particularly if they are part of the additional features associated with each task.

The code also includes the NetworkApplication class, which will be a parent to the classes that you will develop in the coursework. It contains some useful methods that are common across tasks. This includes the checksum function, which calculates a checksum to be used in an ICMP packet. Furthermore, it also includes two methods which are used to print out the results generated ping (see the Example Code 1 section below): printOneResult and printAdditionalDetails.

Finally, it also includes five classes: ICMPPing, Traceroute, MultiThreaded Traceroute, WebServer and Proxy). In the case of ICMPPing and WebServer, they include the complete code as examples for you to study. The Traceroute class is partially implemented; it contains a fully functional UDP traceroute, but not ICMP traceroute.

These classes inherit the NetworkApplication class, allowing you to use the parent’s helper methods (checksum, printOneResult, printAdditionalDetails, and printMultipleResults). These can be called from the child classes. For more details on inheritance in Python, see here:

docs.python.org/3/tutorial/…

Each class contains an init method, called when the object is created (which is done once the command line arguments have been parsed, in this case). This is the starting point for writing the code in each class, but additional methods can be created as required. Important: changing the method signature for any of these init functions will result in zero marks, so please retain all the arguments, including the args object.

SCC. 231 Computer Networks and Systems 2

Practical 1 Network Application Development Michaelmas Term, 2024

To be clear: you can add new methods and code to each of the main classes: Traceroute, MultiThreadedTraceroute and Proxy (and even to the fully-implemented classes Ping and Webserver), but the remaining structure, methods and code must remain intact.

Running your Python script

Once you have the virtual machine setup, you are ready to begin. For this practical, you will be building your applications using Python 3 (as installed on the virtual machine).

To run a Python script, open a Terminal window and navigate to the directory in which the file you want to run is located. To run the script, simply use the following command:

➢ python3 NetworkApplications.py

The above will print the usage information for this program. Please note the use of python3 rather than python: the default command refers to Python 2.7, which we are not using in this course. Using this will result in a different outcome and potential incompatibilities.

When you start this task, the provided code will run successfully and print the help information but do nothing.

Python Library Usage

You are not expected to use any external libraries for this practical; doing so is strictly prohibited. All tasks can be achieved fully with the use of standard Python libraries.

We are also aware of a number of network and IP-orientated libraries that are included within the standard Python distribution. These could potentially be used in different ways to assist in your implementation. However, as we are trying to build your understanding around the fundamentals of computer networks, we ask that you do not use these for this practical, either.

The teaching team believes it is vitally important that you grasp the technical details behind many of these libraries, which do a good job of abstracting and obscuring the details. It is, of course, perfectly acceptable to use these libraries in any future software development you may do, whether this be as part of an upcoming course module or even after graduation.

By following the provided structure and guidance, you will not need to use any of these. If you are in any doubt about whether or not you can use a particular library, please contact the course tutors to confirm.

Submission and Assessment

The submission for all work completed in this practical is due by 4 pm on December 13 th

(Friday, Week 10). All code must be included in a single file titled NetworkApplications.py and submitted on Moodle.

SCC. 231 Computer Networks and Systems 3

Practical 1 Network Application Development Michaelmas Term, 2024

Automated Testing

When marking your code, we will be using an automated testing tool. For the automarking tool to work, it is vital that you follow the guidance described in the ‘Provided/Skeleton Code’ and ‘Submission and Assessment’ sections regarding modifying provided classes, methods and filenames.

Failure to adhere to this will result in loss of marks and possibly a zero mark to be awarded. If you are in any doubt about whether a change or modification is acceptable, please contact the teaching team.

Example Code I: ICMP Ping

A ping client implementation is provided in the skeleton code. We have covered ping in week 2 (third lecture). Remember that ping is a tool used to measure delay and loss in computer networks. It does this by sending messages to another host. Once a message reaches that host, it is returned to the sender. We can determine the sum of nodal delays in the network by measuring the amount of Round-Trip Time (RTT) taken to receive that response. Similarly, by tracking the responses returned, we can determine if any have been lost in the network.

ping traditionally uses Internet Control Message Protocol (ICMP) messages to achieve this behaviour. The example code sends echo request messages (with an ICMP type code of 8). These requests are useful to us because on reaching the client, the client will respond with an echo reply message (with an ICMP type code of 0). By timing the period of time elapsed between sending the request and receiving the reply, we can accurately determine the RTT between the two hosts.

In general, you can get help with running each of the classes: traceroute, mtroute (multithreaded traceroute), webserver, and proxy by issuing a --help (or -h) argument in the terminal:

➢ python3 NetworkApplications.py ping --help Or ➢ python3 NetworkApplications.py ping -h

which will print usage information. In the case of ping, python3 NetworkApplications.py ping -- count 5 --timeout 1 lancs.ac.uk will send five ping probes to Lancaster university server with one second timeout on the receipt of responses. Note that the count and timeout are optional arguments and their default values are defined in setupArgumentParser method.

A timeout on a socket defines the maximum time the socket will wait while trying to receive data before raising an exception. If data is not received within the specified timeout period, the recv and recvfrom methods will throw a socket.timeout exception. This ensures that your program does not get stuck indefinitely waiting for a response and allows you to handle network delays or packet loss more effectively. You can set the timeout using socket.settimeout(seconds).

It is possible to use both socket.SOCK_RAW and socket.SOCK_DGRAM when creating sockets. SOCK_RAW requires privileges, as it gives you a huge amount of control and power over the type and content of packets sent through it. As such, it requires sudo to work. In normal circumstances, a non-privileged version would probably be preferable; you don't always have sudo privileges on a system. This is where SOCK_DGRAM comes in. However, it appears that SOCK_DGRAM, when used to specifically to send ICMP packets, is also a privileged operation within some flavours of Linux (and on the provided VM).

SCC.231 Computer Networks and Systems 4

Practical 1 Network Application Development Michaelmas Term, 2024

For the purposes of this practical, it is therefore recommended that you use SOCK_RAW. Note: normally, using SOCK_RAW requires sudo privileges. On the SCC.231 VM, you can run your code (and use raw sockets) without sudo, but on another machine, you will need sudo access.

The ICMP header contains both an identifier and a sequence number. These can be used by your application to match an echo request with its corresponding echo reply. It is also worth noting that the data included in an echo request packet will be included in its entirety within the corresponding echo reply. Use these features to your advantage.

Example Code 2: UDP Traceroute

We have also provided you with a partially implemented (a single-threaded) Traceroute. In particular, the UDP traceroute implementation is provided. You are encouraged to add the ICMP Traceroute implementation to make this a fully functional Traceroute tool. Please carefully go through the provided UDP implementation before you start working on the ICMP traceroute. Although, the ICMP traceroute is not marked, we strongly recommend that you work on ICMP traceroute, as your code for this part can be re-used in Task 1: MultiThreadedTraceroute.

As discussed in Lecture 3 (week 2), traceroute measures RTT between the host and each hop along the route to a given destination. By default, this tool uses UDP messages with a TimeTo-Live (TTL) value initially set to 1. This ensures we get a response from the first hop, the network device closest to the host on which we run the script. When the message arrives at this device, the TTL counter is decremented. When it reaches 0 (in this case, at the first hop), the message is returned back to the client with an ICMP type of 11. This indicates that TTL has been exceeded. As with the previous task, by measuring the time taken to receive this response, RTT can be calculated at each hop in the network. This process can be repeated, increasing the TTL each time, until we receive a destination unreachable message (with an ICMP type of 3). This tells us that we have reached the destination, so we can stop sending traceroute probes.

To run Traceroute, you can check its usage by:

➢ python3 NetworkApplications.py traceroute --help

The traceroute expects a hostname (similar to ping), and you can provide optional parameters. As an example, to run UDP traceroute to lancs.ac.uk, do:

➢ python3 NetworkApplications.py traceroute --protocol udp lancs.ac.uk

or

➢ python3 NetworkApplications.py traceroute -p udp lancs.ac.uk

The ICMP variant of traceroute operates similarly but uses ICMP Echo Request (Type 8) messages instead of UDP packets. The Time-To-Live (TTL) value is still incremented with each probe, and when the TTL expires at each hop, the router sends back an ICMP Time Exceeded (Type 11) message. The round-trip time (RTT) is measured based on the time it takes for this response to return. Once the probe reaches the final destination, an ICMP Echo Reply (Type 0) is received, indicating that traceroute has successfully completed the path discovery.

When you eventually implement ICMP traceroute, you should be able to run it by:

python3 NetworkApplications.py traceroute -p icmp lancs.ac.uk

SCC.231 Computer Networks and Systems 5

Practical 1 Network Application Development Michaelmas Term, 2024

You can run the real traceroute tool using the traceroute command on the terminal. Note that by default, traceroute uses UDP probes. To send ICMP probes, you must use the -I flag:

➢ traceroute -I lancs.ac.uk

Example Code 3: Web Server

Web Servers are a fundamental part of the Internet; they serve the web pages and content that we are all familiar with. You will be learning more about web servers and the operation of the HTTP protocol in Lecture 6: Application Layer II: Web & HTTP Basics (week 3, lecture 6). Fundamentally, a web server receives an HTTP GET request for an object (usually a file) located on the web server. Once it receives this request, the web server will respond by returning this object back to the requester.

The Web Server differs from the ICMP Ping application in that it will bind to an explicit socket, identified by a port number. This allows the Web Server to listen constantly for incoming requests, responding to each in turn. HTTP traffic is usually bound for port 80, with port 8080 a frequently used alternative. For the purposes of this application, we suggest you bind to a high-numbered port above 1024; these are unprivileged sockets, which reduces the likelihood of conflict with existing running services on the virtual machine.

For example, a request with a URI of 127.0.0.1:8080/index.html, will serve a file name index.html found in the same directory as the Python script itself. The URI is broken down as follows:

• 127.0.0.1: Hostname of web server

• 8080: Port number that web server has bound to

• index.html: File to be served

On successfully finding and loading the file, it will be sent back to client with the appropriate header. This will contain the Status-Code 200, meaning that the file has been found OK, and that it will be delivered to the client as expected. This implementation only serves files from the same directory in which the Python script is executed. To start the WebServer, simply do:

➢ python3 Network Applications.py web -p 8081

Then copy the following URI and paste it into the address bar of your favourite browser: 127.0.0.1:8081/index.html. You must also store an index.html file in the same folder where you run your script. A dummy index.html file is provided in Moodle.

SCC. 231 Computer Networks and Systems 6

Practical 1 Network Application Development Michaelmas Term, 2024

Task 1: A Multithreaded Traceroute Weight: 50% of the total mark for coursework 1

Building on example code 2, this task aims to create a multithreaded traceroute tool.

Implementation Tips

In general, you can find lots of information about the socket library documentation:

docs.python.org/3/library/s…

In this task, you will implement a multithreaded version of the traceroute tool (mtroute), which sends probes and receives responses in parallel using separate threads. A skeleton code is provided in the MultiThreadedTraceRoute class to help you get started. Your task is to complete the implementation of mainly the two methods: send_probes and receive_responses, using the ICMP and UDP protocols (you can also modify the init method and include additional methods as you need).

Your implementation must: • Use one thread to handle the sending of traceroute probes, incrementing the TTL as described earlier. • Use another thread to handle the reception of responses, calculating the round-trip times (RTT). • Ensure thread safety by using locks for shared data, and use thread events to signal when sending is complete (which is already provided in the skeleton code).

Your final implementation should display the traceroute results, including the IP of each hop and the RTT, using the printMultipleResults method.

Debugging and Testing

As with the previous task, every host on the path to your chosen destination should respond to your probes. In reality, these probes are often filtered, including within the lab network. As a result, it is especially difficult to test this tool with a remote host. Instead, it is suggested that you initially test with a closer endpoint that is reachable: lancs.ac.uk. Although the number of hops is small (~5), it can still be used to demonstrate the working of your application. If you run your script whilst attached to a different network, such as at home, your results will likely differ. Once, traceroute to lancs.ac.uk works, you should also test destinations such as google.co.uk that are farther away.

To run UDP multithreaded traceroute with lancs.ac.uk as the target:

➢ python3 NetworkApplications.py mtroute -p udp lancs.ac.uk

To run the ICMP version of the multithreaded traceroute, simply update the -p option:

➢ python3 NetworkApplications.py mtroute -p icmp lancs.ac.uk

SCC. 231 Computer Networks and Systems 7

Practical 1 Network Application Development Michaelmas Term, 2024

Note that your implementation must configure a timeout period to ensure that your program does not get stuck indefinitely waiting for a response. Please see the traceroute implementation on how to configure a timeout.

The threading library is imported into the skeleton code. For more details on the use of threading, please refer to: docs.python.org/3/library/t…

Wireshark can be used to inspect the packets leaving your application. Comparing these to those created using the original traceroute utility will provide a meaningful comparison.

Marking Criteria

The marks will be awarded for ensuring:

  1. A multithreaded UDP (30%) and ICMP (40%) traceroute implementation that sends a train of probe packets while simultaneously receiving and processing responses. (70%)

Note I: Your implementation will be tested on the SCC.231 VM with at least two destinations: lancs.ac.uk and another one such as google.co.uk. The automarker will inspect the packets sent by your program to determine whether your implementation is correct; that is, the packet formats, sequence number handling, TTL management, and so on are accurate.

Note II: your program must use the --protocol(or -p) positional argument to configure the protocol from the command line. The configurability is required for the automarker to test both protocols.

  1. Similar to the original traceroute utility, display three delay measurements for each node between your machine and the chosen destination. You are advised to use the printMultipleResults method in the skeleton code to print the output. (30%).

Note III: Your final submission should not print extra (e.g., debugging) information other than the traceroute output.

SCC. 231 Computer Networks and Systems 8

Practical 1 Network Application Development Michaelmas Term, 2024

Task 2: A Web Proxy Weight: 50% of the total mark for coursework 1

Building on the Web Server example, this task concerns building a Web Proxy. A Proxy operates similarly to a web server, with one significant difference: once configured to use the Proxy Cache application, a client will make all requests for content via this proxy. Normally, when we make a request (without a Web Proxy), the requests travels from the host machine to the destination. The Web Server then processes the request and sends back a response message to the requesting client.

However, when we use a Web Proxy, we place this additional application between the client and the web server. Now, both the request message sent by the client, and the response message delivered by the web server, pass through the Web Proxy. In other words, the client requests the objects via the Web Proxy. The Web Proxy will forward the client’s request to the web server. The web server will then generate a response message and deliver it to the proxy server, which in turn sends it to the client. The message flow is as below:

As with the Web Server, your Web Proxy application is only expected to handle HTTP/1.1 GET requests. Similarly, the Web Proxy will also bind to a specific port (this can be the same as the Web Server) and continue to listen on this port until stopped.

Please ensure that all code for this task is included in the Proxy class.

Debugging and Testing

As with the webserver, there are a number of ways to test your Web Proxy. For example, to generate requests using curl, we can use the following:

curl neverssl.com --proxy 127.0.0.1:8000

This assumes that the Web Proxy is running on the local machine and bound to port 8000.

In this case, the URL requested from the proxy is neverssl.com.

A caveat when testing your Web Proxy: some websites have enabled HTTP Strict Transport Security (HSTS) (RFC6797). This forces clients (including both curl and a web browser) to use HTTPS rather than HTTP. HTTPS is a secure version of HTTP, but we will consider this out of the scope of this practical.

Thanks to the proliferation of HTTPS (this is a good thing, just not for this practical!) the list of live websites you can test the Proxy with is quite limited. A few include:

SCC. 231 Computer Networks and Systems 9

Practical 1 Network Application Development Michaelmas Term, 2024

neverssl.com (see above)

captive.apple.com

It is also possible to run a webserver locally on your virtual machine and test it from that. This could be the web server implementation provided in the code. Alternatively, Python also has a simple implementation that can be run directly from the terminal:

docs.python.org/3/library/h…

As with the other tasks, Wireshark can be used to capture and investigate packets sent to and from your proxy.

Marking Criteria

For this task, marks will be awarded:

  1. A correctly implemented Web Proxy. You are expected to test the functionality of your Proxy using curl, as shown above. Note that you are not expected to use a website with HSTS enabled (see above). (60%)

  2. Binding the Web Proxy to a configurable port, defined as an optional argument (use port positional argument). (10%)

  3. Object caching: A typical Web Proxy will cache the web pages each time the client makes a particular request for the first time. The basic functionality of caching works as follows. When the proxy gets a request, it checks if the requested object is cached, and if yes, it returns the object from the cache, without contacting the server. If the object is not cached, the proxy retrieves the object from the server, returns it to the client and caches a copy for future requests. In practice, the proxy server must verify that the cached responses are still valid and that they are the correct responses to the client's requests. You can read more about caching and its handling in HTTP in RFC2068. Add the simple caching functionality described above. You do not need to implement any replacement or validation policies. Your implementation, however, will need to be able to write responses to the disk (i.e., the cache) and fetch them from the disk when you get a cache hit. For this you need to implement some internal data structure in the proxy to keep track of which objects are cached and where they are on the disk. You can keep this data structure in the main memory; there is no need to make it persist. (30%)

Note: If you implement caching, ensure that your program does NOT use absolute paths (e.g., /home/Alex/project/cache) to the location of your cache file or folder. Doing so will not be compatible with automarking and result in zero marks. Instead, you must use relative paths (e.g., ./cache or subdir/cache).

SCC. 231 Computer Networks and Systems 10

WX:codinghelp