Commit 506bb655 authored by Pedro Oliveira's avatar Pedro Oliveira

minor fixes

parent 179c9207
......@@ -6,7 +6,7 @@ from Packet.PacketPimHello import PacketPimHello
from Packet.PacketPimHeader import PacketPimHeader
from Interface import Interface
import Main
from utils import KEEP_ALIVE_PERIOD_TIMEOUT
from utils import HELLO_HOLD_TIME_TIMEOUT
class Hello:
......@@ -20,7 +20,7 @@ class Hello:
self.thread.start()
def send_handle(self):
for (ip, interface) in list(Main.interfaces.items()):
for (_, interface) in list(Main.interfaces.items()):
self.packet_send_handle(interface)
# reschedule timer
......@@ -44,7 +44,7 @@ class Hello:
# TODO: ver melhor este metodo
def force_send_remove(self, interface: Interface):
pim_payload = PacketPimHello()
pim_payload.add_option(1, KEEP_ALIVE_PERIOD_TIMEOUT)
pim_payload.add_option(1, HELLO_HOLD_TIME_TIMEOUT)
pim_payload.add_option(20, interface.generation_id)
ph = PacketPimHeader(pim_payload)
packet = Packet(pim_header=ph)
......@@ -61,8 +61,13 @@ class Hello:
if Main.get_neighbor(ip) is None:
# Unknown Neighbor
if (1 in options) and (20 in options):
print("non neighbor and options inside")
try:
Main.add_neighbor(packet.interface, ip, options[20], options[1])
print("non neighbor and options inside")
except Exception:
# Received Neighbor with Timeout
print("non neighbor and options inside but neighbor timedout")
pass
return
print("non neighbor and required options not inside")
else:
......@@ -70,9 +75,9 @@ class Hello:
print("neighbor conhecido")
neighbor = Main.get_neighbor(ip)
neighbor.heartbeat()
if 1 in options and neighbor.keep_alive_period != options[1]:
if 1 in options and neighbor.hello_hold_time != options[1]:
print("keep alive period diferente")
neighbor.set_keep_alive_period(options[1])
neighbor.set_hello_hold_time(options[1])
if 20 in options and neighbor.generation_id != options[20]:
print("neighbor reiniciado")
neighbor.remove()
......
import socket
import threading
import random
import netifaces
from Packet.ReceivedPacket import ReceivedPacket
import Main
class Interface:
#IF_IP = "10.0.0.1"
MCAST_GRP = '224.0.0.13'
# substituir ip por interface ou algo parecido
def __init__(self, ip_interface: str):
def __init__(self, interface_name: str):
ip_interface = netifaces.ifaddresses(interface_name)[netifaces.AF_INET][0]['addr']
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_PIM)
# allow other sockets to bind this port too
......@@ -41,7 +43,7 @@ class Interface:
def receive(self):
while self.interface_enabled:
try:
(raw_packet, (ip, p)) = self.socket.recvfrom(256 * 1024)
(raw_packet, (ip, _)) = self.socket.recvfrom(256 * 1024)
if raw_packet:
packet = ReceivedPacket(raw_packet, self)
#print("packet received bytes: ", packet.bytes())
......
......@@ -10,33 +10,41 @@ neighbors = {} # multicast router neighbors
protocols = {}
def add_interface(ip):
def add_interface(interface_name):
global interfaces
if ip not in interfaces:
interface = Interface(ip)
interfaces[ip] = interface
if interface_name not in interfaces:
interface = Interface(interface_name)
interfaces[interface_name] = interface
protocols[0].force_send(interface)
# TODO: verificar melhor este metodo:
def remove_interface(ip):
def remove_interface(interface_name):
# TODO remover neighbors desta interface
global interfaces
global neighbors
if ip in interfaces:
if (interface_name in interfaces) or interface_name == "*":
if interface_name == "*":
interface_name = list(interfaces.keys())
else:
interface_name = [interface_name]
for if_name in interface_name:
protocols[0].force_send_remove(interfaces[if_name])
interfaces[if_name].remove()
del interfaces[if_name]
print("removido interface")
for (ip_neighbor, neighbor) in list(neighbors.items()):
# TODO ver melhor este algoritmo
if neighbor.contact_interface == interfaces[ip]:
if neighbor.contact_interface not in interfaces or interface_name == "*":
neighbor.remove()
protocols[0].force_send_remove(interfaces[ip])
interfaces[ip].remove()
del interfaces[ip]
print("removido interface")
def add_neighbor(contact_interface, ip, random_number, keep_alive_period):
def add_neighbor(contact_interface, ip, random_number, hello_hold_time):
global neighbors
if ip not in neighbors:
print("ADD NEIGHBOR")
neighbors[ip] = Neighbor(contact_interface, ip, random_number, keep_alive_period)
neighbors[ip] = Neighbor(contact_interface, ip, random_number, hello_hold_time)
protocols[0].force_send(contact_interface)
def get_neighbor(ip) -> Neighbor:
......@@ -58,12 +66,12 @@ def add_protocol(protocol_number, protocol_obj):
def list_neighbors():
global neighbors
check_time = time.time()
t = PrettyTable(['Neighbor IP', 'KeepAlive', "Generation ID", "Uptime"])
t = PrettyTable(['Neighbor IP', 'Hello Hold Time', "Generation ID", "Uptime"])
for ip, neighbor in list(neighbors.items()):
uptime = check_time - neighbor.time_of_last_update
uptime = 0 if (uptime < 0) else uptime
t.add_row([ip, neighbor.keep_alive_period, neighbor.generation_id, time.strftime("%H:%M:%S", time.gmtime(uptime))])
t.add_row([ip, neighbor.hello_hold_time, neighbor.generation_id, time.strftime("%H:%M:%S", time.gmtime(uptime))])
print(t)
return str(t)
......@@ -87,14 +95,14 @@ def list_enabled_interfaces():
for interface in netifaces.interfaces():
# TODO: fix same interface with multiple ips
ip = netifaces.ifaddresses(interface)[netifaces.AF_INET][0]['addr']
status = ip in interfaces
status = interface in interfaces
t.add_row([interface, ip, status])
print(t)
return str(t)
def main(ip_interfaces_to_add=[]):
def main(interfaces_to_add=[]):
from Hello import Hello
Hello()
for ip in ip_interfaces_to_add:
add_interface(ip)
for interface in interfaces_to_add:
add_interface(interface)
from threading import Timer
import time
from utils import KEEP_ALIVE_PERIOD_NO_TIMEOUT, KEEP_ALIVE_PERIOD_TIMEOUT
from utils import HELLO_HOLD_TIME_NO_TIMEOUT, HELLO_HOLD_TIME_TIMEOUT
from Interface import Interface
import Main
class Neighbor:
def __init__(self, contact_interface: Interface, ip, generation_id: int, keep_alive_period: int):
def __init__(self, contact_interface: Interface, ip, generation_id: int, hello_hold_time: int):
if hello_hold_time == HELLO_HOLD_TIME_TIMEOUT:
raise Exception
self.contact_interface = contact_interface
self.ip = ip
self.generation_id = generation_id
self.neighbor_liveness_timer = None
self.set_keep_alive_period(keep_alive_period)
self.hello_hold_time = None
self.set_hello_hold_time(hello_hold_time)
self.time_of_last_update = time.time()
def set_keep_alive_period(self, keep_alive_period: int):
self.keep_alive_period = keep_alive_period
def set_hello_hold_time(self, hello_hold_time: int):
self.hello_hold_time = hello_hold_time
if self.neighbor_liveness_timer is not None:
self.neighbor_liveness_timer.cancel()
if keep_alive_period == KEEP_ALIVE_PERIOD_TIMEOUT:
if hello_hold_time == HELLO_HOLD_TIME_TIMEOUT:
self.remove()
elif keep_alive_period != KEEP_ALIVE_PERIOD_NO_TIMEOUT:
self.neighbor_liveness_timer = Timer(4 * keep_alive_period, self.remove)
elif hello_hold_time != HELLO_HOLD_TIME_NO_TIMEOUT:
self.neighbor_liveness_timer = Timer(4 * hello_hold_time, self.remove)
self.neighbor_liveness_timer.start()
else:
self.neighbor_liveness_timer = None
def heartbeat(self):
if (self.keep_alive_period != KEEP_ALIVE_PERIOD_TIMEOUT) and \
(self.keep_alive_period != KEEP_ALIVE_PERIOD_NO_TIMEOUT):
if (self.hello_hold_time != HELLO_HOLD_TIME_TIMEOUT) and \
(self.hello_hold_time != HELLO_HOLD_TIME_NO_TIMEOUT):
print("HEARTBEAT")
if self.neighbor_liveness_timer is not None:
self.neighbor_liveness_timer.cancel()
self.neighbor_liveness_timer = Timer(4 * self.keep_alive_period, self.remove)
self.neighbor_liveness_timer = Timer(4 * self.hello_hold_time, self.remove)
self.neighbor_liveness_timer.start()
self.time_of_last_update = time.time()
......
......@@ -7,14 +7,29 @@ import socket
import sys
import os
import argparse
from argparse import Namespace
def client_socket(data_to_send):
# Create a UDS socket
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
# Connect the socket to the port where the server is listening
server_address = './uds_socket'
print('connecting to %s' % server_address)
try:
sock.connect(server_address)
sock.sendall(pickle.dumps(data_to_send))
data_rcv = sock.recv(1024 * 256)
if data_rcv:
print(pickle.loads(data_rcv))
except socket.error:
pass
finally:
print('closing socket')
sock.close()
class MyDaemon(Daemon):
def stop(self):
print("stopping...")
# TODO: remove all interfaces
super(MyDaemon, self).stop()
class MyDaemon(Daemon):
def run(self):
Main.main()
server_address = './uds_socket'
......@@ -51,11 +66,18 @@ class MyDaemon(Daemon):
elif args.remove_interface:
Main.remove_interface(args.remove_interface[0])
connection.shutdown(socket.SHUT_RDWR)
elif args.stop:
Main.remove_interface("*")
connection.shutdown(socket.SHUT_RDWR)
except Exception:
connection.shutdown(socket.SHUT_RDWR)
finally:
# Clean up the connection
connection.close()
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='PIM')
group = parser.add_mutually_exclusive_group(required=True)
......@@ -64,8 +86,9 @@ if __name__ == "__main__":
group.add_argument("-restart", "--restart", action="store_true", default=False, help="Restart PIM")
group.add_argument("-li", "--list_interfaces", action="store_true", default=False, help="List All PIM Interfaces")
group.add_argument("-ln", "--list_neighbors", action="store_true", default=False, help="List All PIM Neighbors")
group.add_argument("-ai", "--add_interface", nargs=1, metavar='IP_INTERFACE', help="Add PIM interface")
group.add_argument("-ri", "--remove_interface", nargs=1, metavar='IP_INTERFACE', help="Remove PIM interface")
group.add_argument("-mr", "--multicast_routes", action="store_true", default=False, help="List Multicast Routing table")
group.add_argument("-ai", "--add_interface", nargs=1, metavar='INTERFACE_NAME', help="Add PIM interface")
group.add_argument("-ri", "--remove_interface", nargs=1, metavar='INTERFACE_NAME', help="Remove PIM interface")
group.add_argument("-v", "--verbose", action="store_true", default=False, help="Verbose (print all debug messages)")
args = parser.parse_args()
......@@ -77,6 +100,7 @@ if __name__ == "__main__":
daemon.start()
sys.exit(0)
elif args.stop:
client_socket(args)
daemon.stop()
sys.exit(0)
elif args.restart:
......@@ -85,31 +109,12 @@ if __name__ == "__main__":
elif args.verbose:
os.system("tailf stdout")
sys.exit(0)
elif args.multicast_routes:
os.system("ip mroute show")
sys.exit(0)
elif not daemon.is_running():
print("PIM is not running")
parser.print_usage()
sys.exit(0)
# Create a UDS socket
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
# Connect the socket to the port where the server is listening
server_address = './uds_socket'
print('connecting to %s' % server_address)
try:
sock.connect(server_address)
except socket.error:
print("erro socket")
print(sys.stderr)
sys.exit(1)
try:
sock.sendall(pickle.dumps(args))
data = sock.recv(1024 * 256)
if data:
print(pickle.loads(data))
finally:
print('closing socket')
sock.close()
client_socket(args)
......@@ -21,9 +21,9 @@ else:
return (((s>>8)&0xff)|s<<8) & 0xffff
'''
KEEP_ALIVE_PERIOD_NO_TIMEOUT = 0xFFFF
KEEP_ALIVE_PERIOD = 160
KEEP_ALIVE_PERIOD_TIMEOUT = 0
HELLO_HOLD_TIME_NO_TIMEOUT = 0xFFFF
HELLO_HOLD_TIME = 160
HELLO_HOLD_TIME_TIMEOUT = 0
def checksum(pkt: bytes) -> bytes:
......
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