Commit 27e8f125 authored by Pedro Oliveira's avatar Pedro Oliveira

types, remove_interface and socket close

parent 2649abb6
import random
from threading import Timer
from Packet.Packet import Packet
from Packet.ReceivedPacket import ReceivedPacket
from Packet.PacketPimOption import PacketPimOption
from Packet.PacketPimHeader import PacketPimHeader
from Interface import Interface
from Main import Main
from utils import KEEP_ALIVE_PERIOD_TIMEOUT
......@@ -18,7 +20,7 @@ class Hello:
self.thread.start()
def send_handle(self):
for (ip, interface) in Main().interfaces.items():
for (ip, interface) in list(Main().interfaces.items()):
self.force_send_handle(interface)
# reschedule timer
......@@ -27,7 +29,7 @@ class Hello:
self.thread = Timer(hello_timer, self.send_handle)
self.thread.start()
def force_send_handle(self, interface):
def force_send_handle(self, interface: Interface):
ph = PacketPimHeader(Hello.TYPE)
ph.add_option(PacketPimOption(1, Hello.HELLO_HOLD_TIME))
ph.add_option(PacketPimOption(20, interface.generation_id))
......@@ -35,7 +37,7 @@ class Hello:
interface.send(packet.bytes())
# TODO: ver melhor este metodo
def force_send_remove_handle(self, interface):
def force_send_remove_handle(self, interface: Interface):
ph = PacketPimHeader(Hello.TYPE)
ph.add_option(PacketPimOption(1, KEEP_ALIVE_PERIOD_TIMEOUT))
ph.add_option(PacketPimOption(20, interface.generation_id))
......@@ -43,10 +45,10 @@ class Hello:
interface.send(packet.bytes())
# receive handler
def receive_handle(self, packet):
def receive_handle(self, packet: ReceivedPacket):
if packet.ip_header is None:
return # TODO: MAYBE EXCEPCAO??
ip = packet.ip_header.ip
print("ip = ", ip)
# Unknown Neighbor
......@@ -66,7 +68,7 @@ class Hello:
if 1 in options and neighbor.keep_alive_period != options[1]:
print("keep alive period diferente")
neighbor.set_keep_alive_period(options[1])
if 20 in options and neighbor.random_number != options[20]:
if 20 in options and neighbor.generation_id != options[20]:
print("neighbor reiniciado")
neighbor.remove()
main.add_neighbor(packet.interface, ip, options[20], options[1])
......@@ -8,7 +8,7 @@ class Interface:
MCAST_GRP = '224.0.0.13'
# substituir ip por interface ou algo parecido
def __init__(self, ip_interface):
def __init__(self, ip_interface: str):
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_PIM)
# allow other sockets to bind this port too
......@@ -47,8 +47,9 @@ class Interface:
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
def send(self, data):
def send(self, data: bytes):
self.socket.sendto(data, (Interface.MCAST_GRP, 0))
def remove(self):
self.interface_enabled = False
self.socket.close()
import netifaces
from prettytable import PrettyTable
from Interface import Interface
from Neighbor import Neighbor
......@@ -15,12 +17,20 @@ class Main(object):
if ip not in self.interfaces:
interface = Interface(ip)
self.interfaces[ip] = interface
#self.protocols[0].force_send_handle(interface) # force send hello packet to added interface
#self.protocols[0].force_send_handle(interface) # TODO force send hello packet to added interface
# TODO: verificar melhor este metodo:
def remove_interface(self, ip):
self.protocols[0].force_send_remove_handle(self.interfaces[ip])
del self.interfaces[ip]
# TODO remover neighbors desta interface
if ip in self.interfaces:
for (ip_neighbor, neighbor) in list(self.neighbors.items()):
# TODO ver melhor este algoritmo
if neighbor.contact_interface == self.interfaces[ip]:
self.remove_neighbor(ip_neighbor)
self.protocols[0].force_send_remove_handle(self.interfaces[ip])
self.interfaces[ip].remove()
del self.interfaces[ip]
print("removido neighbor")
def add_neighbor(self, contact_interface, ip, random_number, keep_alive_period):
print("ADD NEIGHBOR")
......@@ -28,7 +38,7 @@ class Main(object):
self.neighbors[ip] = Neighbor(contact_interface, ip, random_number, keep_alive_period)
print(self.neighbors.keys())
def get_neighbor(self, ip):
def get_neighbor(self, ip) -> Neighbor:
if ip not in self.neighbors:
return None
return self.neighbors[ip]
......@@ -41,13 +51,15 @@ class Main(object):
self.protocols[protocol_number] = protocol_obj
def list_neighbors(self):
t = PrettyTable(['Neighbor IP', 'KeepAlive', "Random Number"])
for ip, neighbor in self.neighbors.items():
t.add_row([ip, neighbor.keep_alive_period, neighbor.random_number])
t = PrettyTable(['Neighbor IP', 'KeepAlive', "Generation ID"])
for ip, neighbor in list(self.neighbors.items()):
import socket, struct # TODO atualmente conversao manual de numero para string ip
ip = socket.inet_ntoa(struct.pack('!L', ip))
t.add_row([ip, neighbor.keep_alive_period, neighbor.generation_id])
print(t)
def list_enabled_interfaces(self):
t = PrettyTable(['Interface', 'IP', 'Status'])
t = PrettyTable(['Interface', 'IP', 'Enabled'])
for interface in netifaces.interfaces():
# TODO: fix same interface with multiple ips
ip = netifaces.ifaddresses(interface)[netifaces.AF_INET][0]['addr']
......
from threading import Timer
from utils import KEEP_ALIVE_PERIOD_NO_TIMEOUT, KEEP_ALIVE_PERIOD_TIMEOUT
from Interface import Interface
class Neighbor:
def __init__(self, contact_interface, ip, random_number, keep_alive_period):
def __init__(self, contact_interface: Interface, ip, generation_id: int, keep_alive_period: int):
self.contact_interface = contact_interface
self.ip = ip
self.random_number = random_number
self.generation_id = generation_id
self.neighbor_liveness_timer = None
self.set_keep_alive_period(keep_alive_period)
def set_keep_alive_period(self, keep_alive_period):
def set_keep_alive_period(self, keep_alive_period: int):
self.keep_alive_period = keep_alive_period
if self.neighbor_liveness_timer is not None:
self.neighbor_liveness_timer.cancel()
......@@ -32,9 +33,6 @@ class Neighbor:
self.neighbor_liveness_timer = Timer(4 * self.keep_alive_period, self.remove)
self.neighbor_liveness_timer.start()
def send(self, packet):
self.contact_interface.send(self.ip, packet)
def remove(self):
from Main import Main
print('HELLO TIMER EXPIRED... remove neighbor')
......
from Packet.PacketIpHeader import PacketIpHeader
from Packet.PacketPimHeader import PacketPimHeader
from Packet.PacketPimOption import PacketPimOption
class Packet:
# ter ip header
# pim header
# pim options
def __init__(self, ip_header=None, pim_header=None):
def __init__(self, ip_header: PacketIpHeader = None, pim_header: PacketPimHeader = None):
self.ip_header = ip_header
self.pim_header = pim_header
# maybe remover
def add_option(self, option):
'''def add_option(self, option: PacketPimOption):
self.pim_header.add_option(option)
'''
def bytes(self):
return self.pim_header.bytes()
import struct
from utils import checksum
from Packet.PacketPimOption import PacketPimOption
class PacketPimHeader:
......@@ -10,11 +11,11 @@ class PacketPimHeader:
# HELLO: type = 0
# pim options
def __init__(self, msg_type):
def __init__(self, msg_type: int):
self.options = []
self.msg_type = msg_type
def add_option(self, option):
def add_option(self, option: PacketPimOption):
self.options.append(option)
def get_options_bytes(self):
......@@ -32,7 +33,7 @@ class PacketPimHeader:
dictionary[option.option_type] = option.option_value
return dictionary
def bytes(self):
def bytes(self) -> bytes:
# obter mensagem e criar checksum
pim_vrs_type = (PacketPimHeader.PIM_VERSION << 4) + self.msg_type
msg_without_chcksum = struct.pack(PacketPimHeader.PIM_HDR, pim_vrs_type, 0, 0)
......
......@@ -9,11 +9,11 @@ class PacketPimOption:
20: 4,
}
def __init__(self, option_type, option_value):
def __init__(self, option_type: int, option_value: int):
self.option_type = option_type
self.option_value = option_value
def bytes(self):
def bytes(self) -> bytes:
option_length = PacketPimOption.PIM_MSG_TYPES_LENGTH[self.option_type]
msg = struct.pack(PacketPimOption.PIM_HDR_OPTS, self.option_type, option_length)
return msg + struct.pack("! " + str(option_length) + "s", self.option_value.to_bytes(option_length, byteorder='big'))
......
......@@ -12,4 +12,10 @@ ph.add_option(po)
ph.add_option(PacketPimOption(20, 813183289))
packet = Packet(pim_header=ph)
m.interfaces["10.0.0.1"].send(packet.bytes())'''
'''for i in range(0, 5):
m.list_enabled_interfaces()
m.list_neighbors()
time.sleep(10)'''
time.sleep(30)
m.remove_interface("10.0.0.1")
time.sleep(100)
......@@ -26,7 +26,7 @@ KEEP_ALIVE_PERIOD = 160
KEEP_ALIVE_PERIOD_TIMEOUT = 0
def checksum(pkt):
def checksum(pkt: bytes) -> bytes:
if len(pkt) % 2 == 1:
pkt += "\0"
s = sum(array.array("H", pkt))
......
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