aboutsummaryrefslogtreecommitdiff
path: root/README.md
blob: e097c82d39bcfe94bc7f07c2776fef6f015b0a37 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
## Introduction
This project is an implementation of IP pipelines in Go. The project is split into two parts, the first being the IPStack, which is a library that implements the IP pipeline, and the second being the vhost and vrouter, which are the two nodes that are used to test the IPStack.


## Vrouter and Vhost Design
Vrouter and Vhost follow similar designs, with a check to ensure than an lnxconfig file is passed into, to initialize the node with the parsed information from the lnxfiles. For both nodes we register the test protocol handler, and the rip protocol handler specifically for routers. We then listen for command line interfaces, while threads were initialized in the initialization. We follow the specifications of the handout having the following functions and functionality:

li: List interfaces
lr: List routes
ln: List available neighbors
up: Enable an interface
down: Disable an interface
send: Send test packet

Because the vhost and vrouter are so similar, we maintain most of the logic within the IPStack in which the vrouter and vhost call when necessary.

## IPStack Design
We build our abstractions for the IP layer and interfaces with the following structs: 

type Interface struct {

	Name     string
	IpPrefix netip.Prefix
	UdpAddr  netip.AddrPort

	Socket    net.UDPConn
	SocketChannel chan bool
	State         bool

}

type Neighbor struct {

	Name    string
	VipAddr netip.Addr
	UdpAddr netip.AddrPort

}

type RIPHeader struct {

	command    uint16
	numEntries uint16

}

type RIPEntry struct {

	prefix netip.Prefix
	cost   uint32

}

type Hop struct {

	Cost uint32
	Type string
	Interface *Interface
	VIP       netip.Addr

}

With these structs, we are able to maintain the information necessary for the IPStack to function and for the vhost and vrouter to interact with its interfaces, neighbors, and routes when applicable.

# Initialization/Main Thread

First we, parse the lnxfile and populate our the data structures such as myInterfaces, myNeighbors and routingTable based on the specification in the lnx files. For each not we create a UDP listener conn and utilize a go routines to listen on the UDP socket. 

This goroutine is responsible for listening on the UDP socket and handling the packets that are received. The goroutine will hang on the recv and wait for a packet to be received. Once a packet is received, the goroutine will check if the interface is up and handle the packet per the protocol. If the interface is down, the goroutine will drop the packet, and it the channel is closed the thread will close.

## Interface Up/Down

When an interface is brought up or down, the state of the interface is changed and the channel is signaled. If the interface is brought up, the channel is signaled with true, and if the interface is brought down, the channel is signaled with false. The goroutine that is listening on the UDP socket will check the state of the interface and handle the packet accordingly. If the interface is down, the packet will be dropped, and if the interface is up, the packet will be handled per the protocol.

# RIP Threads

## Periodic Updates

Every 5 seconds, a goroutine will send periodic updates to all of its neighbors. The goroutine will iterate through the nodes interfaces and neighbors and send the periodic updates to all of its RIP neighbors by creating and sending the entries to the corroding neighbor.

## Manage Timeouts

Every second, a goroutine will check the timeout table and increment the timeout for each entry. If the timeout is equal to the MAX_TIMEOUT, the entry will be deleted from the timeout table and the routing table. The goroutine will then send a triggered update to all of its neighbors.

## Send Rip Requests
There is a goroutine in RegisterProtocolHandler that will send a RIP request to all of its RIP neighbors. That goroutine will iterate through the nodes interfaces and neighbors and send the RIP request to all of its RIP neighbors by creating and sending the entries to the corroding neighbor. Then the main goroutine will create the periodic update goroutine and the manage timeout goroutine.


# Processing IP packets
We process IP packets in the following way:
We first check if the interface is up, and if it is, we validate the checksum and TTL of the header. If either of these conditions fail, we drop the packet. Then we check who the package is for. If it is for me, I look at the protocol number to determine how to handle the packet. If the packet is not for me, I check my neighbors and routing table and forward the packet accordingly with SendIP. If the packet is not in the routing table, the packet will be dropped.

# Other Design Decisions
We have getter function, printing functions, checksum validation and other functions without our IPStack that either act as helper functions for bigger functions or to provide REPL functionality for the vrouter and vhost. 

# Known Bugs
No known bugs.