PA3 Manual
PA3 Manual
Contents
1 Assignment Overview 2
1.1 Queries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2 Grade Distribution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3 Submission Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.4 Code Quality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2 Introduction 3
3 Background 3
3.1 Link-State Routing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
3.2 Distance-Vector Routing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
4 Provided Code 4
4.1 Download and Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
4.2 Familiarize yourself with the network simulator . . . . . . . . . . . . . . . . . . . . . . . . . . 4
5 Implementation Instructions 5
5.1 Restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
5.2 Method Descriptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
5.3 Dijkstar Package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
5.4 Creating and sending packets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
5.5 Link reliability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
5.6 This is not a network. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
6 Starter Code 8
7 Testing 8
March 2024 1
CS 382 Network Centric Computing
1 Assignment Overview
The goal of this assignment is to introduce you to two commonly used intra-domain routing algorithms:
Link-state Routing and Distance-Vector Routing. The assignment must be done individually, and
you are required to use Python.
1.1 Queries
You should post any assignment related queries ONLY on Slack. Please do not email the course staff
regarding any assignment related queries. This will ensure that everyone benefits from the answers to your
queries.
Please note that your assignment will be tested on Docker containers. As such, it is
recommended for you to run your code on it atleast once before submitting. Should any
compatibility issues arise on our end, you will be given the chance to contest your code.
You should submit your assignment on LMS. You should submit a zip file containing the following:
• DVrouter.py OR LSrouter.py
The zip file should be named <Roll Number>.zip. For example, if your roll number is 24100027, your
submission file should be named 24100027.zip. You should not submit any other files. You will be penalized
(2% of the assignment grade) if you do not follow the submission guidelines.
Bonus: If you submit both DVrouter.py and LSrouter.py and they pass all the tests, you can get a bonus
of 10 points. The bonus points can be used to make up for lost points in any of the assignments.
March 2024 2
CS 382 Network Centric Computing
You are expected to follow good coding practices. We will manually look at your code and award points
based on the following criteria:
• Apporpriate naming conventions followed as specified in the PEP 8 standards. You can find the
standards here. In short, we will be looking at the following:
– Variables, Functions, and Methods: Use lowercase letters and separate words with under-
scores. For example, my_variable, calculate_sum()
– Constants: Use uppercase letters and separate words with underscores. For example,
MAX_SIZE, PI
– Classes: Use CamelCase (capitalize the first letter of each word without underscores). For
example, MyClass, CarModel
• Code modularity and reusability. You should make sure that all of your code is not in a single
function. Try and break it down into smaller functions that can be reused.
• Code readability. You should make sure that your code is readable. This means that your variables
have meaningful names
While these criteria may seem very basic, they are very important in your growth as a programmer. You
should make sure that you follow these practices in all of your code, even beyond this course. It makes your
code more readable and easier to debug.
2 Introduction
The Internet is composed of many independent networks (called autonomous systems) that must cooperate
in order for packets to reach their destinations. This necessitates different protocols and algorithms for
routing packets within autonomous systems, where all routers are operated by the same entity, and between
autonomous systems, where business agreements and other policy considerations affect routing decisions.
This assignment focuses on intra-domain routing algorithms used by routers within a single autonomous
system (AS). The goal of intra-domain routing is typically to forward packets along the shortest or lowest-
cost path through the network.
The need to rapidly handle unexpected router or link failures, changing link costs (usually depending on
traffic volume), and connections from new routers and clients motivates the use of distributed algorithms
for intra-domain routing. In these distributed algorithms, routers start with only their local state and must
communicate with each other to learn the lowest-cost paths.
Many intra-domain routing algorithms used in real-world networks fall into one of two categories: distance-
vector or link-state. In this assignment, you will implement distributed distance-vector and link-state routing
algorithms in Python and test them with a provided network simulator.
3 Background
Begin by reviewing relevant lecture slides on LMS. Read Chapters 4.5.1 and 4.5.2 from the course textbook.
An extract from Computer Networks: A Systems Approach has also been given to you. It provides enough
information to design both the link-state and distance-vector routing algorithms. At a high level, they work
as follows. Your goal in this assignment is to turn this high-level description into the actual working code.
March 2024 3
CS 382 Network Centric Computing
• When a router receives a link-state from its neighbor, it updates the stored link state and the
forwarding table. Then it broadcasts the link state to other neighbors.
• Each router broadcasts its own link state to all neighbors when the link state changes. The broadcast
is also done periodically if no detected change has occurred.
• A sequence number is added to each link-state message to distinguish between old and new link-state
messages. Each router stores the sequence number together with the link state. If a router receives
a link-state message with a smaller sequence number (i.e., an old link-state message), the link-state
message is simply disregarded.
• Each router keeps its own distance-vector, which contains its distance to all destinations.
• When a router receives a distance vector from a neighbor, it updates its own distance vector and
the forwarding table.
• Each router broadcasts its own distance vector to all neighbors when the distance vector changes.
The broadcast is also done periodically if no detected change has occurred.
• Each router does not broadcast the received distance vector to its neighbors. It only broadcasts
its own distance vector to its neighbors.
4 Provided Code
2 In a terminal, execute:
1. sudo apt-get update
2. sudo apt-get install python3 python3-pip python3-tk
3. pip3 install Dijkstar
4. pip3 install networkx
The provided code implements a network simulator that abstracts away many details of a real network,
allowing you to focus on intra-domain routing algorithms. Each .json file in the assignment3 directory is
the specification for a different network simulation with different numbers of routers, links, and link costs.
Some of these simulations also contain link additions and/or failures that will occur at pre-specified times.
The network simulator can be run with or without a graphical interface. For example, the command python3
visualize_network.py test1.json will run the simulator on a simple network with two routers and three
clients. The default router implementation returns all traffic back out of the link on which it arrives. This
is obviously a terrible routing algorithm, which your implementations will fix.
The network architecture is shown on the left side of the visualization. Routers are colored red; clients are
colored blue. Each client periodically sends gray traceroute-like packets addressed to every other client in
the network. These packets remember the sequence of routers they traverse, and the most recent route taken
to each client is printed in the text box on the top right. This is an important debugging tool.
The cost of each link is printed on the connections.
March 2024 4
CS 382 Network Centric Computing
Clicking on a client hides all packets except those addressed to that client, so you can see the path chosen
by the routers. Clicking on the client again will go back to showing all packets.
Clicking on a router causes a string about that router to print in the text box on the lower right. You will
be able to set the contents of this string for debugging your router implementations.
The same network simulation can be run without the graphical interface by the command: python3
network.py test1.json. The simulation will run faster without having to go at a visualizable speed.
It will stop after a predetermined amount of time, print the final routes taken by the traceroute packets to
and from all clients, and whether these routes are correct given the known lowest-cost paths through the
network.
5 Implementation Instructions
Your job is to complete the DVrouter and LSrouter classes in the DVrouter.py and LSrouter.py files so
they implement distance-vector or link-state routing algorithms, respectively.
The simulator will run independent instances of your completed DVrouter or LSrouter classes in separate
threads, simulating independent routers in a network.
You will notice that the DVrouter and LSrouter classes contain several unfinished methods marked with
TODO (including handlePacket, debugString, etc.). These methods override those in the Router superclass
(in router.py) and are called by the simulator when a corresponding event occurs (e.g. handlePacket()
will be called when a router instance receives a packet).
The arguments to these methods contain all the information you need to implement the routing algorithms.
Each of these methods is described in greater detail below.
In addition to completing each of these methods, you are free to add additional fields (instance variables) or
helper methods to the DVrouter and LSrouter classes.
You will be graded on whether your solutions find the lowest-cost paths in the face of link failures and
additions. Here are a few further simplifications:
• Each client and router in the network simulation has a single static address. Do not worry about
address prefixes, families, or masks.
• You do not need to worry about packet authentication and checksums. Assume that a lower layer
protocol handles corruption checking.
• As long as your routers behave correctly when notified of link additions and failures, you do not
need to worry about time-to-live (TTL) fields. The network simulations are short and routers/links
will not fail silently
• The slides discuss the “count-to-infinity” problem for distance-vector routing. You will need to
handle this problem. You can use the heuristic discussed in the slides. Setting infinity = 16 is fine
for the networks in this assignment.
• Link-state routing involves reliably flooding link-state updates. You will need to use sequence
numbers to distinguish new updates from old updates, but you will not need to check (via ac-
knowledgments and retransmissions) that LSPs send successfully between adjacent routers. Assume
that a lower-level protocol makes single-hop sends reliable.
• Link-state routing involves computing the shortest paths. You can choose to implement Dijkstra’s
algorithm, and the pseudo-code is in the slides. Since this is a networking class instead of a data
structures and algorithms class, you can also use a Python package like NetworkX or Dijkstar, we
recommend using Dijkstar.
• Finally, LS and DV routing involve periodically sending routing information even if no detected
change has occurred. This allows changes occurring far away in the network to propagate even
March 2024 5
CS 382 Network Centric Computing
if some routers do not change their routing tables in response to these changes (important for this
assignment). It also allows the detection of silent router failures (not tested in this assignment). Your
implementations should send periodic routing packets every heartbeatTime milliseconds, where
heartbeatTime is an argument to the DVrouter or LSrouter constructor. You will regularly get
the current time in milliseconds as an argument to the handleTime method (see section 5.2).
5.1 Restrictions
There are limitations on what information your DVrouter and LSrouter classes are allowed to access from
the other provided Python files. Unlike C and Java, Python does not support private variables and classes.
Instead, the list of limitations here will be checked when grading. Violating any of these requirements will
result in serious grade penalties.
• Your solution must not require modification to any files other than DVrouter.py and LSrouter.py.
The grading tests will be performed with unchanged versions of the other files.
• Your code may not call any functions or methods, instantiate any classes, or access any variables
defined in any of the other provided python files, with the following exceptions:
– LSrouter and DVrouter can call the inherited send function of the Router superclass (e.g.
self.send(port, packet)).
– LSrouter and DVrouter can access the addr field of the Router superclass (e.g. self.addr) to
get their own address.
– LSrouter and DVrouter can create new Packet objects and call any of the methods defined in
packet.py except for getRoute(), addToRoute(), and animateSend(). You can access and
change any of the fields of a Packet object except for route.
These are the methods you need to complete in DVrouter and LSrouter:
March 2024 6
CS 382 Network Centric Computing
• debugString(self)
This method is called by the network visualization to print current details about the router. It
should return any string that will be helpful for debugging. This method is for your own use
and will not be graded.
These are the methods you need to be familiar with from the Dijkstar package:
• add_edge(u, v, cost):
Adds an edge from u to v. If the graph is undirected (as in this assignment), the edge will be
added from v to u too.
• remove_edge(u, v):
Removes the edge from u to v.
• find_path(graph, u, v):
Given a graph, it finds a path from u to v. It returns a PathInfo object containing the following:
∗ A list of nodes on the path
∗ A list of edges on the path
∗ The costs of edges on the path
∗ Total path cost
For Dijkstar usage examples, please see the official project site here.
If you choose to use NetworkX, please see its official documentation here.
You will need to create packets to send information between routers using the Packet class defined in
packet.py. Any packet p you create to send routing information should have p.kind == ROUTING.
You will have to decide what to include in the content field of these packets. The content should be
reasonable for the algorithm you are implementing (e.g. don’t send an entire routing table for link state
routing).
Packet content must be a string. This is checked by an assert statement when the packet is sent. DVrouter
and LSrouter import the dumps() and loads() functions that return a string (in JSON format) when
given a python object. Using these functions is an easy way to stringify and destringify.
You can access and set/modify any of the fields of a packet object (including content, srcAddr, dstAdddr,
and kind) except for route (see section 5.1).
If a link between two routers fails or is added, the appropriate handle function will always be called on both
routers after the failure or addition.
Links have varying latencies (usually proportional to their costs). Packets may not arrive in the global order
that they are sent.
The simulated network in this assignment abstracts away many details you would need to consider when
implementing distance-vector or link-state algorithms on real routers. This should allow you to focus on
the core ideas of the algorithms without worrying about other protocols (e.g. ARP) or meticulous systems
programming issues. If you are curious about these real-world details, please ask on Slock or office hours.
March 2024 7
CS 382 Network Centric Computing
6 Starter Code
You have been provided with the following files in the Code directory:
PA3
docker-compose.yml
Code
client.py
DVRouter.py
link.py
LSRouter.py
network.py
packet.py
router.py
test1.json
test2.json
test3.json
test4.json
test5.json
visualize_network.py
Manual
PA3.pdf
7 Testing
You should test your DVrouter and LSrouter using the provided network simulator. There are multi-
ple JSON files defining different network architectures and link failures and additions. test3.json and
test4.json files define the networks on pages 242 and 244 of the provided reading. The JSON files without
“events” in their file name do not have link failures or additions and are good for initial testing.
If you use visual_network.py, understanding the JSON files is not necessary. However, it may still be
useful to understand the changes and links sections.
• The links section in the JSON contains a list of all the edges in the network graph. The structure is
as follows: [node1, node2, port1, port2, cost1, cost2]. You don’t have to worry about the
ports, and since the graph is undirected, cost1 and cost2 are always equal.
Example: ["A", "b", 1, 1, 3, 3] – An edge from A to b with cost 3.
• The changes section contains a list of all link changes that will occur in the network at different
times. There are two types of changes:
– Up: can be a new link or an update to an existing link.
Example: [12, ["G", "F", 2, 2, 1, 1], "up"] – An edge from node G to F is added
at time 12.
– Down: removal of a link
Example: [32, ["E", "G"], "down"] – An edge from node E to G is removed at time 32.
To run the simulation with the graphical interface, use the following command (The argument DV or LS
indicates whether to run DVrouter or LSrouter, respectively):
1 $ python3 visualize_network.py <networkSimulationFile.json> [DV|LS]
To run the simulation without the graphical interface, use the following command (The argument DV or LS
indicates whether to run DVrouter or LSrouter, respectively):
1 $ python3 network.py <networkSimulationFile.json> [DV|LS]
March 2024 8
CS 382 Network Centric Computing
The routes to and from each client at the end of the simulation will print, along with whether they match
the reference lowest-cost routes. If the routes match, your implementation has passed for that simulation.
If they do not, continue debugging (using print statements and the debugString() method in your router
classes)
Grading for the assignment will be done on the provided Docker container. You have been provided a
docker-compose.yml file in the root directory.
This file will create a container that you can run whenever you want. The container will have all the
dependencies installed and will have the starter code mounted in the /home/netcen-spring-2024 directory.
A detailed video tutorial of this process is available on YouTube, including how to set it up to work with
Visual Studio Code. You are recommended to watch it immediately after reading this document. Click here
to watch the video.
Please note that you will only need to run the following commands once to set up the container.
To create the container, open the docker-compose.yml in a text editor and replace the line
1 image: jazlan/netcen-spring-2024:${ARCH}
with whatever architecture you have (refer to the Docker Guide on LMS).
For example, if you have an x86_64 architecture, you will replace the line with
1 image: jazlan/netcen-spring-2024:x86_64
Then you can simply run the following command in a terminal or command prompt shell.
1 docker-compose up -d
This will create a container with the name netcen and will mount the current directory in the
/home/netcen-spring-2024 directory of the container. This way you will be able to access the files from
your system in the container.
To enter the container from any terminal session, run the following command:
1 docker exec -it netcen /bin/bash
Now you can simply run the commands in section 7 as if you were running them on your system.
Once you are done with the assignment, open the Assignment folder in a terminal or command prompt and
run the following command:
1 docker-compose down
This will shut down the container and free up your CPU resources. If you used our Docker image in
a previous assignment, please shut down any running containers before starting one for this
assignment.
Please note that we do NOT require you to use Docker. This is for your convenience only. There are some
instances in which students have reported that the code runs on their system but not on the grading server.
This is because of the difference in the environment. If you are confident that your code will run on the
grading server, you do not need to use Docker. However, if you are not sure, we recommend that you use
Docker to test your code.
March 2024 9