Commit 4e436aa9 authored by Pedro Oliveira's avatar Pedro Oliveira

fixed remove neighbor bug and random timer when interface/neighbor added

parent 27e8f125
...@@ -11,33 +11,37 @@ from utils import KEEP_ALIVE_PERIOD_TIMEOUT ...@@ -11,33 +11,37 @@ from utils import KEEP_ALIVE_PERIOD_TIMEOUT
class Hello: class Hello:
TYPE = 0 TYPE = 0
HELLO_HOLD_TIME = 16 # TODO: configure via external file?? TRIGGERED_HELLO_DELAY = 16 # TODO: configure via external file??
def __init__(self): def __init__(self):
Main().add_protocol(Hello.TYPE, self) Main().add_protocol(Hello.TYPE, self)
self.thread = Timer(0, self.send_handle) self.thread = Timer(Hello.TRIGGERED_HELLO_DELAY, self.send_handle)
self.thread.start() self.thread.start()
def send_handle(self): def send_handle(self):
for (ip, interface) in list(Main().interfaces.items()): for (ip, interface) in list(Main().interfaces.items()):
self.force_send_handle(interface) self.packet_send_handle(interface)
# reschedule timer # reschedule timer
# Hello Timer(HT) MUST be set to random value between 0 and Triggered_Hello_Delay self.thread = Timer(Hello.TRIGGERED_HELLO_DELAY, self.send_handle)
hello_timer = random.uniform(0, Hello.HELLO_HOLD_TIME)
self.thread = Timer(hello_timer, self.send_handle)
self.thread.start() self.thread.start()
def force_send_handle(self, interface: Interface): def packet_send_handle(self, interface: Interface):
ph = PacketPimHeader(Hello.TYPE) ph = PacketPimHeader(Hello.TYPE)
ph.add_option(PacketPimOption(1, Hello.HELLO_HOLD_TIME)) ph.add_option(PacketPimOption(1, Hello.TRIGGERED_HELLO_DELAY))
ph.add_option(PacketPimOption(20, interface.generation_id)) ph.add_option(PacketPimOption(20, interface.generation_id))
packet = Packet(pim_header=ph) packet = Packet(pim_header=ph)
interface.send(packet.bytes()) interface.send(packet.bytes())
def force_send(self, interface: Interface):
# When PIM is enabled on an interface or when a router first starts, the Hello Timer (HT)
# MUST be set to random value between 0 and Triggered_Hello_DelayHello Timer(HT)
hello_timer = random.uniform(0, Hello.TRIGGERED_HELLO_DELAY)
Timer(hello_timer, self.packet_send_handle, args=[interface]).start()
# TODO: ver melhor este metodo # TODO: ver melhor este metodo
def force_send_remove_handle(self, interface: Interface): def force_send_remove(self, interface: Interface):
ph = PacketPimHeader(Hello.TYPE) ph = PacketPimHeader(Hello.TYPE)
ph.add_option(PacketPimOption(1, KEEP_ALIVE_PERIOD_TIMEOUT)) ph.add_option(PacketPimOption(1, KEEP_ALIVE_PERIOD_TIMEOUT))
ph.add_option(PacketPimOption(20, interface.generation_id)) ph.add_option(PacketPimOption(20, interface.generation_id))
...@@ -51,18 +55,18 @@ class Hello: ...@@ -51,18 +55,18 @@ class Hello:
ip = packet.ip_header.ip ip = packet.ip_header.ip
print("ip = ", ip) print("ip = ", ip)
# Unknown Neighbor
main = Main() main = Main()
options = packet.pim_header.get_options() options = packet.pim_header.get_options()
if main.get_neighbor(ip) is None: if main.get_neighbor(ip) is None:
# Unknown Neighbor
if (1 in options) and (20 in options): if (1 in options) and (20 in options):
print("entrou... non neighbor and options inside") print("non neighbor and options inside")
main.add_neighbor(packet.interface, ip, options[20], options[1]) main.add_neighbor(packet.interface, ip, options[20], options[1])
return return
print("entrou... non neighbor and no options inside") print("non neighbor and required options not inside")
# Already know Neighbor
else: else:
print("entrou... neighbor conhecido") # Already know Neighbor
print("neighbor conhecido")
neighbor = main.get_neighbor(ip) neighbor = main.get_neighbor(ip)
neighbor.heartbeat() neighbor.heartbeat()
if 1 in options and neighbor.keep_alive_period != options[1]: if 1 in options and neighbor.keep_alive_period != options[1]:
......
...@@ -40,16 +40,24 @@ class Interface: ...@@ -40,16 +40,24 @@ class Interface:
def receive(self): def receive(self):
from Main import Main from Main import Main
while self.interface_enabled: while self.interface_enabled:
try:
(raw_packet, (ip, p)) = self.socket.recvfrom(256 * 1024) (raw_packet, (ip, p)) = self.socket.recvfrom(256 * 1024)
packet = ReceivedPacket(raw_packet, self) packet = ReceivedPacket(raw_packet, self)
print("packet received bytes: ", packet.bytes()) #print("packet received bytes: ", packet.bytes())
print("pim type received = ", packet.pim_header.msg_type) #print("pim type received = ", packet.pim_header.msg_type)
print("generation id received = ", packet.pim_header.options[1].option_value) #print("generation id received = ", packet.pim_header.options[1].option_value)
Main().protocols[packet.pim_header.msg_type].receive_handle(packet) # TODO: perceber se existe melhor maneira de fazer isto Main().protocols[packet.pim_header.msg_type].receive_handle(packet) # TODO: perceber se existe melhor maneira de fazer isto
except Exception:
pass
def send(self, data: bytes): def send(self, data: bytes):
if self.interface_enabled:
self.socket.sendto(data, (Interface.MCAST_GRP, 0)) self.socket.sendto(data, (Interface.MCAST_GRP, 0))
def remove(self): def remove(self):
self.interface_enabled = False self.interface_enabled = False
try:
self.socket.shutdown(socket.SHUT_RDWR)
except Exception:
pass
self.socket.close() self.socket.close()
import netifaces import netifaces
from prettytable import PrettyTable from prettytable import PrettyTable
from Interface import Interface from Interface import Interface
from Neighbor import Neighbor from Neighbor import Neighbor
...@@ -17,7 +15,7 @@ class Main(object): ...@@ -17,7 +15,7 @@ class Main(object):
if ip not in self.interfaces: if ip not in self.interfaces:
interface = Interface(ip) interface = Interface(ip)
self.interfaces[ip] = interface self.interfaces[ip] = interface
#self.protocols[0].force_send_handle(interface) # TODO force send hello packet to added interface self.protocols[0].force_send(interface)
# TODO: verificar melhor este metodo: # TODO: verificar melhor este metodo:
def remove_interface(self, ip): def remove_interface(self, ip):
...@@ -26,17 +24,17 @@ class Main(object): ...@@ -26,17 +24,17 @@ class Main(object):
for (ip_neighbor, neighbor) in list(self.neighbors.items()): for (ip_neighbor, neighbor) in list(self.neighbors.items()):
# TODO ver melhor este algoritmo # TODO ver melhor este algoritmo
if neighbor.contact_interface == self.interfaces[ip]: if neighbor.contact_interface == self.interfaces[ip]:
self.remove_neighbor(ip_neighbor) neighbor.remove()
self.protocols[0].force_send_remove_handle(self.interfaces[ip]) self.protocols[0].force_send_remove(self.interfaces[ip])
self.interfaces[ip].remove() self.interfaces[ip].remove()
del self.interfaces[ip] del self.interfaces[ip]
print("removido neighbor") print("removido interface")
def add_neighbor(self, contact_interface, ip, random_number, keep_alive_period): def add_neighbor(self, contact_interface, ip, random_number, keep_alive_period):
print("ADD NEIGHBOR")
if ip not in self.neighbors: if ip not in self.neighbors:
print("ADD NEIGHBOR")
self.neighbors[ip] = Neighbor(contact_interface, ip, random_number, keep_alive_period) self.neighbors[ip] = Neighbor(contact_interface, ip, random_number, keep_alive_period)
print(self.neighbors.keys()) self.protocols[0].force_send(contact_interface)
def get_neighbor(self, ip) -> Neighbor: def get_neighbor(self, ip) -> Neighbor:
if ip not in self.neighbors: if ip not in self.neighbors:
...@@ -46,6 +44,7 @@ class Main(object): ...@@ -46,6 +44,7 @@ class Main(object):
def remove_neighbor(self, ip): def remove_neighbor(self, ip):
if ip in self.neighbors: if ip in self.neighbors:
del self.neighbors[ip] del self.neighbors[ip]
print("removido neighbor")
def add_protocol(self, protocol_number, protocol_obj): def add_protocol(self, protocol_number, protocol_obj):
self.protocols[protocol_number] = protocol_obj self.protocols[protocol_number] = protocol_obj
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment