-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLSrouter.py
147 lines (102 loc) · 5.06 KB
/
LSrouter.py
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import sys
from dijkstar import Graph, find_path
from collections import defaultdict
from router import Router
from packet import Packet
from json import dumps, loads
class LSrouter(Router):
"""Link state routing protocol implementation."""
def __init__(self, addr, heartbeatTime):
"""TODO: add your own class fields and initialization code here"""
Router.__init__(self, addr) # initialize superclass - don't remove
self.heartbeatTime = heartbeatTime
self.last_time = 0
self.G=Graph(undirected=True)
self.SeqNum={}
self.Neighbours={} #Dictionary with key as address and cost and seqnum as values
self.Curr_Seq=0
# Hints: initialize local state
def handlePacket(self, port, packet):
"""TODO: process incoming packet"""
if packet.isTraceroute():
# Hints: this is a normal data packet
# if the forwarding table contains packet.dstAddr
# send packet based on forwarding table, e.g., self.send(port, packet)
try:
Shortest=find_path(self.G,self.addr,packet.dstAddr)
self.send(self.Neighbours[Shortest.nodes[1]]['Port'],packet)
except:
return
else:
# Hints: this is a routing packet generated by your routing protocol
# check the sequence number
# if the sequence number is higher and the received link state is different
# update the local copy of the link state
# update the forwarding table
# broadcast the packet to other neighbors
Cont=loads(packet.content)
#Cont[0] is the sender
#Cont[1] is sender neighbours
#Cont[2] is seqnum
if Cont[0] in self.SeqNum.keys(): # Node in SeqNum dictionary
if Cont[2] <= self.SeqNum[Cont[0]]: # Discard packet as it is old
return
self.SeqNum[Cont[0]]=Cont[2]
if Cont[0] in self.G.keys():
if len(Cont[1]) < len(self.G[Cont[0]]):
for node in self.G[Cont[0]]:
if node not in Cont[1]: # Link Removed
self.G.remove_edge(Cont[0],node)
break
else: #Link added or updated
for key,_ in Cont[1].items():
self.G.add_edge(Cont[0], key, Cont[1][key]['Cost'])
for key,_ in self.Neighbours.items(): #Packet Flooding
if (key==Cont[0]):
continue
self.send(self.Neighbours[key]['Port'],packet)
def handleNewLink(self, port, endpoint, cost):
"""TODO: handle new link"""
# Hints:
# update the forwarding table
# broadcast the new link state of this router to all neighbors
# print("\nSelf.Addr: ",self.addr,"Endpoint: ",endpoint, "Cost: ",cost, "Port: ",port)
self.G.add_edge(self.addr, endpoint, cost)
self.Neighbours[endpoint]={}
self.Neighbours[endpoint]['Cost']=cost
self.Neighbours[endpoint]['Port']=port
self.Curr_Seq=self.Curr_Seq+1
Content=dumps([self.addr, self.Neighbours,self.Curr_Seq])
for key,_ in self.Neighbours.items():
Pack=Packet(Packet.ROUTING,self.addr,self.Neighbours[key],Content)
self.send(self.Neighbours[key]['Port'],Pack)
def handleRemoveLink(self, port):
"""TODO: handle removed link"""
# Hints:
# update the forwarding table
# broadcast the new link state of this router to all neighbors
for key,_ in self.Neighbours.items():
if self.Neighbours[key]['Port']==port:
Link=key
break
del self.Neighbours[Link]
self.G.remove_edge(self.addr,Link)
self.Curr_Seq=self.Curr_Seq+1
Content=dumps([self.addr, self.Neighbours,self.Curr_Seq])
for k,_ in self.Neighbours.items():
Pack=Packet(Packet.ROUTING,self.addr,self.Neighbours[k],Content)
self.send(self.Neighbours[k]['Port'],Pack)
def handleTime(self, timeMillisecs):
"""TODO: handle current time"""
if timeMillisecs - self.last_time >= self.heartbeatTime:
# Hints:
# broadcast the link state of this router to all neighbors
self.Curr_Seq=self.Curr_Seq+1
Content=dumps([self.addr, self.Neighbours,self.Curr_Seq])
for k,_ in self.Neighbours.items():
Pack=Packet(Packet.ROUTING,self.addr,self.Neighbours[k],Content)
self.send(self.Neighbours[k]['Port'],Pack)
self.last_time = timeMillisecs
def debugString(self):
"""TODO: generate a string for debugging in network visualizer"""
return ""