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

minor fixes

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