diff --git a/hpimdm/InterfaceHPIM.py b/hpimdm/InterfaceHPIM.py index 520a1cc..1b9aa28 100644 --- a/hpimdm/InterfaceHPIM.py +++ b/hpimdm/InterfaceHPIM.py @@ -223,7 +223,7 @@ def get_checkpoint_sn(self): """ Get the CheckpointSN to be transmitted in a new Hello message """ - print("A ENTRAR CHECK_SN") + print("ENTER CHECK_SN") with self.neighbors_lock: with self.sequencer_lock: with self.reliable_transmission_lock: @@ -235,7 +235,7 @@ def get_checkpoint_sn(self): if msg_boot_time == time_of_boot and checkpoint_sn > msg_checkpoint_sn: checkpoint_sn = msg_checkpoint_sn - print("A SAIR CHECK_SN") + print("EXIT CHECK_SN") return (time_of_boot, checkpoint_sn) #Random interval for initial Hello message on bootup or triggered Hello message to a rebooting neighbor diff --git a/hpimdm/InterfaceIGMP.py b/hpimdm/InterfaceIGMP.py index 66764f7..a3b3c0c 100644 --- a/hpimdm/InterfaceIGMP.py +++ b/hpimdm/InterfaceIGMP.py @@ -6,7 +6,8 @@ from hpimdm.packet.ReceivedPacket import ReceivedPacket from hpimdm.Interface import Interface -from hpimdm.igmp.igmp_globals import Version_1_Membership_Report, Version_2_Membership_Report, Leave_Group, Membership_Query +from hpimdm.igmp.igmp_globals import VERSION_1_MEMBERSHIP_REPORT, VERSION_2_MEMBERSHIP_REPORT, LEAVE_GROUP,\ + MEMBERSHIP_QUERY if not hasattr(socket, 'SO_BINDTODEVICE'): socket.SO_BINDTODEVICE = 25 @@ -125,10 +126,10 @@ def receive_unknown_type(self, packet): return PKT_FUNCTIONS = { - Version_1_Membership_Report: receive_version_1_membership_report, - Version_2_Membership_Report: receive_version_2_membership_report, - Leave_Group: receive_leave_group, - Membership_Query: receive_membership_query, + VERSION_1_MEMBERSHIP_REPORT: receive_version_1_membership_report, + VERSION_2_MEMBERSHIP_REPORT: receive_version_2_membership_report, + LEAVE_GROUP: receive_leave_group, + MEMBERSHIP_QUERY: receive_membership_query, } ################## diff --git a/hpimdm/Kernel.py b/hpimdm/Kernel.py index 44159c7..0fbd2b6 100644 --- a/hpimdm/Kernel.py +++ b/hpimdm/Kernel.py @@ -26,8 +26,9 @@ def __init__(self, kernel_socket): # Kernel is running self.running = True - # KEY : interface_ip, VALUE : vif_index + # KEY : vif_index, VALUE : interface_name self.vif_index_to_name_dic = {} + # KEY : interface_name, VALUE : vif_index self.vif_name_to_index_dic = {} # KEY : source_ip, VALUE : {group_ip: KernelEntry} @@ -36,7 +37,7 @@ def __init__(self, kernel_socket): self.socket = kernel_socket self.rwlock = RWLockWrite() - self.hpim_interface = {} # name: interface_protocol + self.hpim_interface = {} # name: interface_protocol self.membership_interface = {} # name: interface_igmp # logs @@ -218,7 +219,7 @@ def recv_upstream_msg(self, source_group, interface: "InterfaceHPIM"): ip_src = source_group[0] ip_dst = source_group[1] - print("ENTROU RCV_UPSTREAM") + print("ENTER RCV_UPSTREAM") with self.rwlock.genWlock(): if interface not in self.hpim_interface.values(): return @@ -226,7 +227,7 @@ def recv_upstream_msg(self, source_group, interface: "InterfaceHPIM"): (interest_state, upstream_state) = interface.get_tree_state(source_group) tree_is_not_inactive = upstream_state is not None print("RCV INSTALL/UNINSTALL") - print("INTERESSE: ", interest_state) + print("INTEREST: ", interest_state) if tree_is_not_inactive and (ip_src not in self.routing or ip_dst not in self.routing.get(ip_src, {})): self.create_entry(ip_src, ip_dst) @@ -234,13 +235,13 @@ def recv_upstream_msg(self, source_group, interface: "InterfaceHPIM"): self.routing[ip_src][ip_dst].check_interface_state(interface.vif_index, upstream_state, interest_state) else: interface.remove_tree_state(ip_src, ip_dst) - print("SAIU RCV_UPSTREAM") + print("EXIT RCV_UPSTREAM") def recv_interest_msg(self, source_group, interface: "InterfaceHPIM"): ip_src = source_group[0] ip_dst = source_group[1] - print("ENTROU RECV_INTEREST") + print("ENTER RECV_INTEREST") with self.rwlock.genRlock(): if interface not in self.hpim_interface.values(): return @@ -251,7 +252,7 @@ def recv_interest_msg(self, source_group, interface: "InterfaceHPIM"): (interest_state, upstream_state) = interface.get_tree_state(source_group) self.routing[ip_src][ip_dst].check_interest_state(interface.vif_index, interest_state) - print("SAIU RECV_INTEREST") + print("EXIT RECV_INTEREST") ############################################################# # Create kernel entries (data structure representing a tree) @@ -291,18 +292,18 @@ def _get_kernel_entry_interface(): def snapshot_multicast_routing_table(self, vif_index): trees_to_sync = {} - print("ENTROU SNAPSHOT") + print("ENTER SNAPSHOT") #with self.rwlock.genWlock(): for (ip_src, src_dict) in self.routing.items(): for (ip_dst, kernel_entry) in self.routing[ip_src].items(): tree = kernel_entry.get_interface_sync_state(vif_index) if tree is not None: trees_to_sync[(ip_src, ip_dst)] = tree - print("SAIU SNAPSHOT") + print("EXIT SNAPSHOT") return trees_to_sync def recheck_all_trees(self, vif_index: int): - print("ENTROU RECHECK") + print("ENTER RECHECK") with self.rwlock.genWlock(): interface_name = self.vif_index_to_name_dic.get(vif_index, None) interface = self.hpim_interface.get(interface_name, None) @@ -331,15 +332,15 @@ def recheck_all_trees(self, vif_index: int): self.create_entry(tree[0], tree[1]) elif tree[0] in self.routing and tree[1] in self.routing[tree[0]]: self.routing[tree[0]][tree[1]].check_interface_state(vif_index, upstream_state, interest_state) - print("SAIU RECHECK") + print("EXIT RECHECK") def recheck_membership_all_trees(self, vif_index: int): - print("ENTROU RECHECK IGMP") + print("ENTER RECHECK IGMP") with self.rwlock.genWlock(): for src_dict in self.routing.values(): for entry in src_dict.values(): entry.check_membership_state(vif_index) - print("SAIU RECHECK IGMP") + print("EXIT RECHECK IGMP") def recheck_all_trees_in_all_interfaces(self): for i in list(self.vif_index_to_name_dic.keys()): @@ -378,9 +379,15 @@ class Kernel4(KernelInterface): VIFF_USE_IFINDEX = 0x8 # use vifc_lcl_ifindex instead of vifc_lcl_addr to find an interface def __init__(self): - # KEY : interface_ip, VALUE : vif_index s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IGMP) + # MRT TABLE + if hpim_globals.MULTICAST_TABLE_ID != 0: + try: + s.setsockopt(socket.IPPROTO_IP, Kernel4.MRT_TABLE, hpim_globals.MULTICAST_TABLE_ID) + except: + traceback.print_exc() + # MRT INIT s.setsockopt(socket.IPPROTO_IP, Kernel4.MRT_INIT, 1) @@ -655,11 +662,15 @@ class Kernel6(KernelInterface): MIFF_REGISTER = 0x1 # /* register vif */ def __init__(self): - # KEY : source_ip, VALUE : {group_ip: KernelEntry} - self.routing = {} - s = socket.socket(socket.AF_INET6, socket.SOCK_RAW, socket.IPPROTO_ICMPV6) + # MRT TABLE + if hpim_globals.MULTICAST_TABLE_ID != 0: + try: + s.setsockopt(socket.IPPROTO_IPV6, Kernel6.MRT6_TABLE, hpim_globals.MULTICAST_TABLE_ID) + except: + traceback.print_exc() + # MRT INIT s.setsockopt(socket.IPPROTO_IPV6, Kernel6.MRT6_INIT, 1) diff --git a/hpimdm/Run.py b/hpimdm/Run.py index 2817797..f50acda 100644 --- a/hpimdm/Run.py +++ b/hpimdm/Run.py @@ -7,10 +7,11 @@ import traceback import faulthandler import _pickle as pickle +from hpimdm.tree import hpim_globals from hpimdm.daemon.Daemon import Daemon from hpimdm import Main -VERSION = "1.3.2" +VERSION = "1.3.3.1" def client_socket(data_to_send): @@ -220,9 +221,9 @@ def main(): sys.exit(0) elif args.multicast_routes: if args.ipv4 or not args.ipv6: - os.system("ip mroute show") + os.system("ip mroute show table " + str(hpim_globals.MULTICAST_TABLE_ID)) elif args.ipv6: - os.system("ip -6 mroute show") + os.system("ip -6 mroute show table " + str(hpim_globals.MULTICAST_TABLE_ID)) sys.exit(0) elif not daemon.is_running(): print("HPIM-DM is not running") diff --git a/hpimdm/UnicastRouting.py b/hpimdm/UnicastRouting.py index 1158b7c..b832ede 100644 --- a/hpimdm/UnicastRouting.py +++ b/hpimdm/UnicastRouting.py @@ -3,6 +3,7 @@ from threading import RLock from socket import if_indextoname from pyroute2 import IPDB, IPRoute +from .tree import hpim_globals def get_unicast_info(ip_dst): @@ -34,23 +35,25 @@ def get_route(ip_dst: str): raise Exception("Unknown IP version") info = None with UnicastRouting.lock: - ipdb = UnicastRouting.ipdb # type:IPDB + ipdb = UnicastRouting.ipdb # type:IPDB for mask_len in range(full_mask, 0, -1): dst_network = str(ipaddress.ip_interface(ip_dst + "/" + str(mask_len)).network) print(dst_network) - if dst_network in ipdb.routes: + if dst_network in ipdb.routes.tables[hpim_globals.UNICAST_TABLE_ID]: print(info) - if ipdb.routes[{'dst': dst_network, 'family': family}]['ipdb_scope'] != 'gc': - info = ipdb.routes[dst_network] + if ipdb.routes[{'dst': dst_network, 'family': family, + 'table': hpim_globals.UNICAST_TABLE_ID}]['ipdb_scope'] != 'gc': + info = ipdb.routes[{'dst': dst_network, 'family': family, + 'table': hpim_globals.UNICAST_TABLE_ID}] break else: continue if not info: print("0.0.0.0/0 or ::/0") - if "default" in ipdb.routes: - info = ipdb.routes[{'dst': 'default', 'family': family}] + if "default" in ipdb.routes.tables[hpim_globals.UNICAST_TABLE_ID]: + info = ipdb.routes[{'dst': 'default', 'family': family, 'table': hpim_globals.UNICAST_TABLE_ID}] print(info) return info diff --git a/hpimdm/igmp/GroupState.py b/hpimdm/igmp/GroupState.py index 7d54934..cc293c8 100644 --- a/hpimdm/igmp/GroupState.py +++ b/hpimdm/igmp/GroupState.py @@ -4,7 +4,7 @@ from hpimdm.utils import TYPE_CHECKING from .wrapper import NoMembersPresent -from .igmp_globals import GroupMembershipInterval, LastMemberQueryInterval +from .igmp_globals import GROUP_MEMBERSHIP_INTERVAL, LAST_MEMBER_QUERY_INTERVAL if TYPE_CHECKING: from .RouterState import RouterState @@ -49,13 +49,13 @@ def set_state(self, state): ########################################### # Set timers ########################################### - def set_timer(self, alternative: bool=False, max_response_time: int=None): + def set_timer(self, alternative: bool = False, max_response_time: int = None): """ Set timer """ self.clear_timer() if not alternative: - time = GroupMembershipInterval + time = GROUP_MEMBERSHIP_INTERVAL else: time = self.router_state.interface_state.get_group_membership_time(max_response_time) @@ -75,7 +75,7 @@ def set_v1_host_timer(self): Set v1 host timer """ self.clear_v1_host_timer() - v1_host_timer = Timer(GroupMembershipInterval, self.group_membership_v1_timeout) + v1_host_timer = Timer(GROUP_MEMBERSHIP_INTERVAL, self.group_membership_v1_timeout) v1_host_timer.start() self.v1_host_timer = v1_host_timer @@ -91,7 +91,7 @@ def set_retransmit_timer(self): Set retransmit timer """ self.clear_retransmit_timer() - retransmit_timer = Timer(LastMemberQueryInterval, self.retransmit_timeout) + retransmit_timer = Timer(LAST_MEMBER_QUERY_INTERVAL, self.retransmit_timeout) retransmit_timer.start() self.retransmit_timer = retransmit_timer diff --git a/hpimdm/igmp/RouterState.py b/hpimdm/igmp/RouterState.py index 8da38d8..b512ff4 100644 --- a/hpimdm/igmp/RouterState.py +++ b/hpimdm/igmp/RouterState.py @@ -9,7 +9,7 @@ from .GroupState import GroupState from .querier.Querier import Querier from .nonquerier.NonQuerier import NonQuerier -from .igmp_globals import Membership_Query, QueryResponseInterval, QueryInterval, OtherQuerierPresentInterval +from .igmp_globals import MEMBERSHIP_QUERY, QUERY_RESPONSE_INTERVAL, QUERY_INTERVAL, OTHER_QUERIER_PRESENT_INTERVAL if TYPE_CHECKING: from hpimdm.InterfaceIGMP import InterfaceIGMP @@ -37,11 +37,11 @@ def __init__(self, interface: 'InterfaceIGMP'): self.group_state_lock = RWLockWrite() # send general query - packet = PacketIGMPHeader(type=Membership_Query, max_resp_time=QueryResponseInterval*10) + packet = PacketIGMPHeader(type=MEMBERSHIP_QUERY, max_resp_time=QUERY_RESPONSE_INTERVAL * 10) self.interface.send(packet.bytes()) # set initial general query timer - timer = Timer(QueryInterval, self.general_query_timeout) + timer = Timer(QUERY_INTERVAL, self.general_query_timeout) timer.start() self.general_query_timer = timer @@ -63,7 +63,7 @@ def set_general_query_timer(self): Set general query timer """ self.clear_general_query_timer() - general_query_timer = Timer(QueryInterval, self.general_query_timeout) + general_query_timer = Timer(QUERY_INTERVAL, self.general_query_timeout) general_query_timer.start() self.general_query_timer = general_query_timer @@ -79,7 +79,7 @@ def set_other_querier_present_timer(self): Set other querier present timer """ self.clear_other_querier_present_timer() - other_querier_present_timer = Timer(OtherQuerierPresentInterval, self.other_querier_present_timeout) + other_querier_present_timer = Timer(OTHER_QUERIER_PRESENT_INTERVAL, self.other_querier_present_timeout) other_querier_present_timer.start() self.other_querier_present_timer = other_querier_present_timer @@ -137,10 +137,6 @@ def receive_v1_membership_report(self, packet: ReceivedPacket): Received IGMP Version 1 Membership Report packet """ igmp_group = packet.payload.group_address - #if igmp_group not in self.group_state: - # self.group_state[igmp_group] = GroupState(self, igmp_group) - - #self.group_state[igmp_group].receive_v1_membership_report() self.get_group_state(igmp_group).receive_v1_membership_report() def receive_v2_membership_report(self, packet: ReceivedPacket): @@ -148,10 +144,6 @@ def receive_v2_membership_report(self, packet: ReceivedPacket): Received IGMP Membership Report packet """ igmp_group = packet.payload.group_address - #if igmp_group not in self.group_state: - # self.group_state[igmp_group] = GroupState(self, igmp_group) - - #self.group_state[igmp_group].receive_v2_membership_report() self.get_group_state(igmp_group).receive_v2_membership_report() def receive_leave_group(self, packet: ReceivedPacket): @@ -159,8 +151,6 @@ def receive_leave_group(self, packet: ReceivedPacket): Received IGMP Leave packet """ igmp_group = packet.payload.group_address - #if igmp_group in self.group_state: - # self.group_state[igmp_group].receive_leave_group() self.get_group_state(igmp_group).receive_leave_group() def receive_query(self, packet: ReceivedPacket): @@ -172,9 +162,7 @@ def receive_query(self, packet: ReceivedPacket): # process group specific query if igmp_group != "0.0.0.0" and igmp_group in self.group_state: - #if igmp_group != "0.0.0.0": max_response_time = packet.payload.max_resp_time - #self.group_state[igmp_group].receive_group_specific_query(max_response_time) self.get_group_state(igmp_group).receive_group_specific_query(max_response_time) def remove(self): diff --git a/hpimdm/igmp/igmp_globals.py b/hpimdm/igmp/igmp_globals.py index feda4ac..18c5f66 100644 --- a/hpimdm/igmp/igmp_globals.py +++ b/hpimdm/igmp/igmp_globals.py @@ -1,20 +1,20 @@ # IGMP timers (in seconds) -RobustnessVariable = 2 -QueryInterval = 125 -QueryResponseInterval = 10 -MaxResponseTime_QueryResponseInterval = QueryResponseInterval*10 -GroupMembershipInterval = RobustnessVariable * QueryInterval + QueryResponseInterval -OtherQuerierPresentInterval = RobustnessVariable * QueryInterval + QueryResponseInterval/2 -StartupQueryInterval = QueryInterval / 4 -StartupQueryCount = RobustnessVariable -LastMemberQueryInterval = 1 -MaxResponseTime_LastMemberQueryInterval = LastMemberQueryInterval*10 -LastMemberQueryCount = RobustnessVariable -UnsolicitedReportInterval = 10 -Version1RouterPresentTimeout = 400 +ROBUSTNESS_VARIABLE = 2 +QUERY_INTERVAL = 125 +QUERY_RESPONSE_INTERVAL = 10 +MAX_RESPONSE_TIME_QUERY_RESPONSE_INTERVAL = QUERY_RESPONSE_INTERVAL * 10 +GROUP_MEMBERSHIP_INTERVAL = ROBUSTNESS_VARIABLE * QUERY_INTERVAL + QUERY_RESPONSE_INTERVAL +OTHER_QUERIER_PRESENT_INTERVAL = ROBUSTNESS_VARIABLE * QUERY_INTERVAL + QUERY_RESPONSE_INTERVAL / 2 +STARTUP_QUERY_INTERVAL = QUERY_INTERVAL / 4 +STARTUP_QUERY_COUNT = ROBUSTNESS_VARIABLE +LAST_MEMBER_QUERY_INTERVAL = 1 +MAX_RESPONSE_TIME_LAST_MEMBER_QUERY_INTERVAL = LAST_MEMBER_QUERY_INTERVAL * 10 +LAST_MEMBER_QUERY_COUNT = ROBUSTNESS_VARIABLE +UNSOLICITED_REPORT_INTERVAL = 10 +VERSION_1_ROUTER_PRESENT_TIMEOUT = 400 # IGMP msg type -Membership_Query = 0x11 -Version_1_Membership_Report = 0x12 -Version_2_Membership_Report = 0x16 -Leave_Group = 0x17 +MEMBERSHIP_QUERY = 0x11 +VERSION_1_MEMBERSHIP_REPORT = 0x12 +VERSION_2_MEMBERSHIP_REPORT = 0x16 +LEAVE_GROUP = 0x17 diff --git a/hpimdm/igmp/nonquerier/NonQuerier.py b/hpimdm/igmp/nonquerier/NonQuerier.py index 12374bc..a6a1b08 100644 --- a/hpimdm/igmp/nonquerier/NonQuerier.py +++ b/hpimdm/igmp/nonquerier/NonQuerier.py @@ -1,6 +1,6 @@ from ipaddress import IPv4Address -from hpimdm.igmp.igmp_globals import Membership_Query, QueryResponseInterval, LastMemberQueryCount +from hpimdm.igmp.igmp_globals import MEMBERSHIP_QUERY, QUERY_RESPONSE_INTERVAL, LAST_MEMBER_QUERY_COUNT from hpimdm.utils import TYPE_CHECKING from hpimdm.packet.ReceivedPacket import ReceivedPacket from hpimdm.packet.PacketIGMPHeader import PacketIGMPHeader @@ -31,7 +31,7 @@ def other_querier_present_timeout(router_state: 'RouterState'): router_state.change_interface_state(querier=True) # send general query - packet = PacketIGMPHeader(type=Membership_Query, max_resp_time=QueryResponseInterval*10) + packet = PacketIGMPHeader(type=MEMBERSHIP_QUERY, max_resp_time=QUERY_RESPONSE_INTERVAL * 10) router_state.interface.send(packet.bytes()) # set general query timer @@ -62,7 +62,7 @@ def get_group_membership_time(max_response_time: int): """ Get time to set timer* """ - return (max_response_time/10.0) * LastMemberQueryCount + return (max_response_time/10.0) * LAST_MEMBER_QUERY_COUNT # State @staticmethod diff --git a/hpimdm/igmp/querier/CheckingMembership.py b/hpimdm/igmp/querier/CheckingMembership.py index ed35167..4653b8e 100644 --- a/hpimdm/igmp/querier/CheckingMembership.py +++ b/hpimdm/igmp/querier/CheckingMembership.py @@ -1,6 +1,6 @@ from hpimdm.packet.PacketIGMPHeader import PacketIGMPHeader from hpimdm.utils import TYPE_CHECKING -from hpimdm.igmp.igmp_globals import Membership_Query, LastMemberQueryInterval +from hpimdm.igmp.igmp_globals import MEMBERSHIP_QUERY, LAST_MEMBER_QUERY_INTERVAL from ..wrapper import NoMembersPresent, MembersPresent, Version1MembersPresent if TYPE_CHECKING: from ..GroupState import GroupState @@ -33,7 +33,8 @@ def retransmit_timeout(group_state: 'GroupState'): """ group_state.group_state_logger.debug('Querier CheckingMembership: retransmit_timeout') group_addr = group_state.group_ip - packet = PacketIGMPHeader(type=Membership_Query, max_resp_time=LastMemberQueryInterval*10, group_address=group_addr) + packet = PacketIGMPHeader(type=MEMBERSHIP_QUERY, max_resp_time=LAST_MEMBER_QUERY_INTERVAL * 10, + group_address=group_addr) group_state.router_state.send(data=packet.bytes(), address=group_addr) group_state.set_retransmit_timer() diff --git a/hpimdm/igmp/querier/MembersPresent.py b/hpimdm/igmp/querier/MembersPresent.py index ad1c2ef..33c3108 100644 --- a/hpimdm/igmp/querier/MembersPresent.py +++ b/hpimdm/igmp/querier/MembersPresent.py @@ -1,6 +1,6 @@ from hpimdm.packet.PacketIGMPHeader import PacketIGMPHeader from hpimdm.utils import TYPE_CHECKING -from hpimdm.igmp.igmp_globals import Membership_Query, LastMemberQueryInterval +from hpimdm.igmp.igmp_globals import MEMBERSHIP_QUERY, LAST_MEMBER_QUERY_INTERVAL from ..wrapper import Version1MembersPresent, CheckingMembership, NoMembersPresent if TYPE_CHECKING: from ..GroupState import GroupState @@ -63,7 +63,8 @@ def receive_leave_group(group_state: 'GroupState'): group_state.set_timer(alternative=True) group_state.set_retransmit_timer() - packet = PacketIGMPHeader(type=Membership_Query, max_resp_time=LastMemberQueryInterval*10, group_address=group_ip) + packet = PacketIGMPHeader(type=MEMBERSHIP_QUERY, max_resp_time=LAST_MEMBER_QUERY_INTERVAL * 10, + group_address=group_ip) group_state.router_state.send(data=packet.bytes(), address=group_ip) group_state.set_state(CheckingMembership) diff --git a/hpimdm/igmp/querier/Querier.py b/hpimdm/igmp/querier/Querier.py index 5390f93..0104a32 100644 --- a/hpimdm/igmp/querier/Querier.py +++ b/hpimdm/igmp/querier/Querier.py @@ -1,7 +1,8 @@ from ipaddress import IPv4Address from hpimdm.utils import TYPE_CHECKING -from hpimdm.igmp.igmp_globals import Membership_Query, QueryResponseInterval, LastMemberQueryCount, LastMemberQueryInterval +from hpimdm.igmp.igmp_globals import MEMBERSHIP_QUERY, QUERY_RESPONSE_INTERVAL, LAST_MEMBER_QUERY_COUNT, \ + LAST_MEMBER_QUERY_INTERVAL from hpimdm.packet.PacketIGMPHeader import PacketIGMPHeader from hpimdm.packet.ReceivedPacket import ReceivedPacket @@ -19,7 +20,7 @@ def general_query_timeout(router_state: 'RouterState'): """ router_state.router_state_logger.debug('Querier state: general_query_timeout') # send general query - packet = PacketIGMPHeader(type=Membership_Query, max_resp_time=QueryResponseInterval*10) + packet = PacketIGMPHeader(type=MEMBERSHIP_QUERY, max_resp_time=QUERY_RESPONSE_INTERVAL * 10) router_state.interface.send(packet.bytes()) # set general query timer @@ -66,7 +67,7 @@ def get_group_membership_time(max_response_time: int): """ Get time to set timer* """ - return LastMemberQueryInterval * LastMemberQueryCount + return LAST_MEMBER_QUERY_INTERVAL * LAST_MEMBER_QUERY_COUNT # State diff --git a/hpimdm/igmp/wrapper/NoMembersPresent.py b/hpimdm/igmp/wrapper/NoMembersPresent.py index 4455b3c..2aa0b08 100644 --- a/hpimdm/igmp/wrapper/NoMembersPresent.py +++ b/hpimdm/igmp/wrapper/NoMembersPresent.py @@ -2,6 +2,7 @@ if TYPE_CHECKING: from ..RouterState import RouterState + def get_state(router_state: 'RouterState'): return router_state.interface_state.get_no_members_present_state() diff --git a/hpimdm/mld/GroupState.py b/hpimdm/mld/GroupState.py index 4b5e8e9..4b72a84 100644 --- a/hpimdm/mld/GroupState.py +++ b/hpimdm/mld/GroupState.py @@ -4,7 +4,7 @@ from hpimdm.utils import TYPE_CHECKING from .wrapper import NoListenersPresent -from .mld_globals import MulticastListenerInterval, LastListenerQueryInterval +from .mld_globals import MULTICAST_LISTENER_INTERVAL, LAST_LISTENER_QUERY_INTERVAL if TYPE_CHECKING: from .RouterState import RouterState @@ -48,13 +48,13 @@ def set_state(self, state): ########################################### # Set timers ########################################### - def set_timer(self, alternative: bool=False, max_response_time: int=None): + def set_timer(self, alternative: bool = False, max_response_time: int = None): """ Set timer """ self.clear_timer() if not alternative: - time = MulticastListenerInterval + time = MULTICAST_LISTENER_INTERVAL else: time = self.router_state.interface_state.get_group_membership_time(max_response_time) @@ -74,7 +74,7 @@ def set_retransmit_timer(self): Set retransmit timer """ self.clear_retransmit_timer() - retransmit_timer = Timer(LastListenerQueryInterval, self.retransmit_timeout) + retransmit_timer = Timer(LAST_LISTENER_QUERY_INTERVAL, self.retransmit_timeout) retransmit_timer.start() self.retransmit_timer = retransmit_timer diff --git a/hpimdm/mld/RouterState.py b/hpimdm/mld/RouterState.py index 5807e05..dee1bd6 100644 --- a/hpimdm/mld/RouterState.py +++ b/hpimdm/mld/RouterState.py @@ -1,14 +1,16 @@ import logging from threading import Timer -from hpimdm.packet.PacketMLDHeader import PacketMLDHeader -from hpimdm.packet.ReceivedPacket import ReceivedPacket from hpimdm.utils import TYPE_CHECKING from hpimdm.rwlock.RWLock import RWLockWrite + +from .GroupState import GroupState from .querier.Querier import Querier from .nonquerier.NonQuerier import NonQuerier -from .GroupState import GroupState -from .mld_globals import QueryResponseInterval, QueryInterval, OtherQuerierPresentInterval, MULTICAST_LISTENER_QUERY_TYPE +from hpimdm.packet.ReceivedPacket import ReceivedPacket +from hpimdm.packet.PacketMLDHeader import PacketMLDHeader +from .mld_globals import QUERY_RESPONSE_INTERVAL, QUERY_INTERVAL, OTHER_QUERIER_PRESENT_INTERVAL, \ + MULTICAST_LISTENER_QUERY_TYPE if TYPE_CHECKING: from hpimdm.InterfaceMLD import InterfaceMLD @@ -36,11 +38,11 @@ def __init__(self, interface: 'InterfaceMLD'): self.group_state_lock = RWLockWrite() # send general query - packet = PacketMLDHeader(type=MULTICAST_LISTENER_QUERY_TYPE, max_resp_delay=QueryResponseInterval*1000) + packet = PacketMLDHeader(type=MULTICAST_LISTENER_QUERY_TYPE, max_resp_delay=QUERY_RESPONSE_INTERVAL * 1000) self.interface.send(packet.bytes()) # set initial general query timer - timer = Timer(QueryInterval, self.general_query_timeout) + timer = Timer(QUERY_INTERVAL, self.general_query_timeout) timer.start() self.general_query_timer = timer @@ -62,7 +64,7 @@ def set_general_query_timer(self): Set general query timer """ self.clear_general_query_timer() - general_query_timer = Timer(QueryInterval, self.general_query_timeout) + general_query_timer = Timer(QUERY_INTERVAL, self.general_query_timeout) general_query_timer.start() self.general_query_timer = general_query_timer @@ -78,7 +80,7 @@ def set_other_querier_present_timer(self): Set other querier present timer """ self.clear_other_querier_present_timer() - other_querier_present_timer = Timer(OtherQuerierPresentInterval, self.other_querier_present_timeout) + other_querier_present_timer = Timer(OTHER_QUERIER_PRESENT_INTERVAL, self.other_querier_present_timeout) other_querier_present_timer.start() self.other_querier_present_timer = other_querier_present_timer @@ -136,10 +138,6 @@ def receive_report(self, packet: ReceivedPacket): Received MLD Report packet """ mld_group = packet.payload.group_address - #if igmp_group not in self.group_state: - # self.group_state[igmp_group] = GroupState(self, igmp_group) - - #self.group_state[igmp_group].receive_v2_membership_report() self.get_group_state(mld_group).receive_report() def receive_done(self, packet: ReceivedPacket): @@ -147,8 +145,6 @@ def receive_done(self, packet: ReceivedPacket): Received MLD Done packet """ mld_group = packet.payload.group_address - #if igmp_group in self.group_state: - # self.group_state[igmp_group].receive_leave_group() self.get_group_state(mld_group).receive_done() def receive_query(self, packet: ReceivedPacket): @@ -160,9 +156,7 @@ def receive_query(self, packet: ReceivedPacket): # process group specific query if mld_group != "::" and mld_group in self.group_state: - #if igmp_group != "0.0.0.0": max_response_time = packet.payload.max_resp_delay - #self.group_state[igmp_group].receive_group_specific_query(max_response_time) self.get_group_state(mld_group).receive_group_specific_query(max_response_time) def remove(self): diff --git a/hpimdm/mld/mld_globals.py b/hpimdm/mld/mld_globals.py index 882063d..028d6b2 100644 --- a/hpimdm/mld/mld_globals.py +++ b/hpimdm/mld/mld_globals.py @@ -1,14 +1,14 @@ -#MLD timers (in seconds) -RobustnessVariable = 2 -QueryInterval = 125 -QueryResponseInterval = 10 -MulticastListenerInterval = (RobustnessVariable * QueryInterval) + (QueryResponseInterval) -OtherQuerierPresentInterval = (RobustnessVariable * QueryInterval) + 0.5 * QueryResponseInterval -StartupQueryInterval = (1/4) * QueryInterval -StartupQueryCount = RobustnessVariable -LastListenerQueryInterval = 1 -LastListenerQueryCount = RobustnessVariable -UnsolicitedReportInterval = 10 +# MLD timers (in seconds) +ROBUSTNESS_VARIABLE = 2 +QUERY_INTERVAL = 125 +QUERY_RESPONSE_INTERVAL = 10 +MULTICAST_LISTENER_INTERVAL = (ROBUSTNESS_VARIABLE * QUERY_INTERVAL) + (QUERY_RESPONSE_INTERVAL) +OTHER_QUERIER_PRESENT_INTERVAL = (ROBUSTNESS_VARIABLE * QUERY_INTERVAL) + 0.5 * QUERY_RESPONSE_INTERVAL +STARTUP_QUERY_INTERVAL = (1 / 4) * QUERY_INTERVAL +STARTUP_QUERY_COUNT = ROBUSTNESS_VARIABLE +LAST_LISTENER_QUERY_INTERVAL = 1 +LAST_LISTENER_QUERY_COUNT = ROBUSTNESS_VARIABLE +UNSOLICITED_REPORT_INTERVAL = 10 # MLD msg type diff --git a/hpimdm/mld/nonquerier/ListenersPresent.py b/hpimdm/mld/nonquerier/ListenersPresent.py index 0ed4e06..5f91a2b 100644 --- a/hpimdm/mld/nonquerier/ListenersPresent.py +++ b/hpimdm/mld/nonquerier/ListenersPresent.py @@ -50,5 +50,3 @@ def retransmit_timeout(group_state: 'GroupState'): group_state.group_state_logger.debug('NonQuerier ListenersPresent: retransmit_timeout') # do nothing return - - diff --git a/hpimdm/mld/nonquerier/NonQuerier.py b/hpimdm/mld/nonquerier/NonQuerier.py index c329761..c2faf27 100644 --- a/hpimdm/mld/nonquerier/NonQuerier.py +++ b/hpimdm/mld/nonquerier/NonQuerier.py @@ -1,6 +1,6 @@ from ipaddress import IPv6Address from hpimdm.utils import TYPE_CHECKING -from ..mld_globals import QueryResponseInterval, LastListenerQueryCount +from ..mld_globals import QUERY_RESPONSE_INTERVAL, LAST_LISTENER_QUERY_COUNT from hpimdm.packet.PacketMLDHeader import PacketMLDHeader from hpimdm.packet.ReceivedPacket import ReceivedPacket from . import NoListenersPresent, ListenersPresent, CheckingListeners @@ -30,7 +30,7 @@ def other_querier_present_timeout(router_state: 'RouterState'): # send general query packet = PacketMLDHeader(type=PacketMLDHeader.MULTICAST_LISTENER_QUERY_TYPE, - max_resp_delay=QueryResponseInterval*1000) + max_resp_delay=QUERY_RESPONSE_INTERVAL * 1000) router_state.interface.send(packet.bytes()) # set general query timer @@ -61,7 +61,7 @@ def get_group_membership_time(max_response_time: int): """ Get time to set timer* """ - return (max_response_time/1000.0) * LastListenerQueryCount + return (max_response_time/1000.0) * LAST_LISTENER_QUERY_COUNT # State @staticmethod diff --git a/hpimdm/mld/querier/CheckingListeners.py b/hpimdm/mld/querier/CheckingListeners.py index 5ed5c74..d342b2e 100644 --- a/hpimdm/mld/querier/CheckingListeners.py +++ b/hpimdm/mld/querier/CheckingListeners.py @@ -1,6 +1,6 @@ from hpimdm.packet.PacketMLDHeader import PacketMLDHeader from hpimdm.utils import TYPE_CHECKING -from ..mld_globals import LastListenerQueryInterval +from ..mld_globals import LAST_LISTENER_QUERY_INTERVAL from ..wrapper import ListenersPresent, NoListenersPresent if TYPE_CHECKING: from ..GroupState import GroupState @@ -53,9 +53,7 @@ def retransmit_timeout(group_state: 'GroupState'): group_state.group_state_logger.debug('Querier CheckingListeners: retransmit_timeout') group_addr = group_state.group_ip packet = PacketMLDHeader(type=PacketMLDHeader.MULTICAST_LISTENER_QUERY_TYPE, - max_resp_delay=LastListenerQueryInterval*1000, group_address=group_addr) + max_resp_delay=LAST_LISTENER_QUERY_INTERVAL * 1000, group_address=group_addr) group_state.router_state.send(data=packet.bytes(), address=group_addr) group_state.set_retransmit_timer() - - diff --git a/hpimdm/mld/querier/ListenersPresent.py b/hpimdm/mld/querier/ListenersPresent.py index 0748cdf..ac4d054 100644 --- a/hpimdm/mld/querier/ListenersPresent.py +++ b/hpimdm/mld/querier/ListenersPresent.py @@ -1,6 +1,6 @@ from hpimdm.packet.PacketMLDHeader import PacketMLDHeader from hpimdm.utils import TYPE_CHECKING -from ..mld_globals import LastListenerQueryInterval +from ..mld_globals import LAST_LISTENER_QUERY_INTERVAL from ..wrapper import CheckingListeners, NoListenersPresent if TYPE_CHECKING: from ..GroupState import GroupState @@ -25,7 +25,7 @@ def receive_done(group_state: 'GroupState'): group_state.set_retransmit_timer() packet = PacketMLDHeader(type=PacketMLDHeader.MULTICAST_LISTENER_QUERY_TYPE, - max_resp_delay=LastListenerQueryInterval*1000, group_address=group_ip) + max_resp_delay=LAST_LISTENER_QUERY_INTERVAL * 1000, group_address=group_ip) group_state.router_state.send(data=packet.bytes(), address=group_ip) group_state.set_state(CheckingListeners) @@ -58,5 +58,3 @@ def retransmit_timeout(group_state: 'GroupState'): group_state.group_state_logger.debug('Querier ListenersPresent: retransmit_timeout') # do nothing return - - diff --git a/hpimdm/mld/querier/NoListenersPresent.py b/hpimdm/mld/querier/NoListenersPresent.py index 3d2f8d8..61d225a 100644 --- a/hpimdm/mld/querier/NoListenersPresent.py +++ b/hpimdm/mld/querier/NoListenersPresent.py @@ -50,4 +50,3 @@ def retransmit_timeout(group_state: 'GroupState'): group_state.group_state_logger.debug('Querier NoListenersPresent: retransmit_timeout') # do nothing return - diff --git a/hpimdm/mld/querier/Querier.py b/hpimdm/mld/querier/Querier.py index 44c6c9a..c8c966d 100644 --- a/hpimdm/mld/querier/Querier.py +++ b/hpimdm/mld/querier/Querier.py @@ -1,7 +1,7 @@ from ipaddress import IPv6Address from hpimdm.utils import TYPE_CHECKING -from ..mld_globals import LastListenerQueryInterval, LastListenerQueryCount, QueryResponseInterval +from ..mld_globals import LAST_LISTENER_QUERY_INTERVAL, LAST_LISTENER_QUERY_COUNT, QUERY_RESPONSE_INTERVAL from hpimdm.packet.PacketMLDHeader import PacketMLDHeader from hpimdm.packet.ReceivedPacket import ReceivedPacket @@ -41,7 +41,7 @@ def general_query_timeout(router_state: 'RouterState'): router_state.router_state_logger.debug('Querier state: general_query_timeout') # send general query packet = PacketMLDHeader(type=PacketMLDHeader.MULTICAST_LISTENER_QUERY_TYPE, - max_resp_delay=QueryResponseInterval*1000) + max_resp_delay=QUERY_RESPONSE_INTERVAL * 1000) router_state.interface.send(packet.bytes()) # set general query timer @@ -66,7 +66,7 @@ def get_group_membership_time(max_response_time: int): """ Get time to set timer* """ - return LastListenerQueryInterval * LastListenerQueryCount + return LAST_LISTENER_QUERY_INTERVAL * LAST_LISTENER_QUERY_COUNT # State @staticmethod diff --git a/hpimdm/mld/wrapper/NoListenersPresent.py b/hpimdm/mld/wrapper/NoListenersPresent.py index 67c647d..15eabff 100644 --- a/hpimdm/mld/wrapper/NoListenersPresent.py +++ b/hpimdm/mld/wrapper/NoListenersPresent.py @@ -2,6 +2,7 @@ if TYPE_CHECKING: from ..RouterState import RouterState + def get_state(router_state: 'RouterState'): return router_state.interface_state.get_no_listeners_present_state() diff --git a/hpimdm/packet/PacketIGMPHeader.py b/hpimdm/packet/PacketIGMPHeader.py index 7e8d951..6c857fc 100644 --- a/hpimdm/packet/PacketIGMPHeader.py +++ b/hpimdm/packet/PacketIGMPHeader.py @@ -1,6 +1,6 @@ import struct -from hpimdm.utils import checksum import socket +from hpimdm.utils import checksum from .PacketPayload import PacketPayload ''' 0 1 2 3 @@ -41,7 +41,7 @@ class PacketIGMPHeader(PacketPayload): Leave_Group = 0x17 Version_1_Membership_Report = 0x12 - def __init__(self, type: int, max_resp_time: int, group_address: str="0.0.0.0"): + def __init__(self, type: int, max_resp_time: int, group_address: str = "0.0.0.0"): # todo check type self.type = type self.max_resp_time = max_resp_time diff --git a/hpimdm/tree/KernelEntry.py b/hpimdm/tree/KernelEntry.py index 89eaf63..9d02791 100644 --- a/hpimdm/tree/KernelEntry.py +++ b/hpimdm/tree/KernelEntry.py @@ -81,14 +81,14 @@ def check_interface_state(self, index, upstream_state, interest_state): """ if index not in self.interface_state or self.is_tree_inactive(): return - print("ENTROU CHECK INTERFACE STATE") + print("ENTER CHECK INTERFACE STATE") self._upstream_interface_state[index] = upstream_state self.interface_state[index].change_best_upstream_neighbor_state(upstream_state) self.check_interest_state(index, interest_state) self.check_tree_state() - print("SAI CHECK INTERFACE STATE") + print("EXIT CHECK INTERFACE STATE") def check_interest_state(self, index, interest_state): """ @@ -109,12 +109,12 @@ def check_membership_state(self, index): Reverify IGMP/MLD state of this tree in interface with VIF index... This is invoked whenever interface index enables or disables IGMP/MLD """ - print("ENTROU CHECK IGMP STATE") + print("ENTER CHECK IGMP STATE") if index not in self.interface_state: return self.interface_state[index].check_membership_state() - print("SAI CHECK IGMP STATE") + print("EXIT CHECK IGMP STATE") def get_interface_sync_state(self, vif_index): """ @@ -316,7 +316,7 @@ def check_tree_state(self): len(self.interface_state) > 0 and\ self._upstream_interface_state.get(self.inbound_interface_index, None) is not None and \ (not self._rpc.is_better_than(self._upstream_interface_state.get(self.inbound_interface_index)) - and self._rpc != self._upstream_interface_state.get(self.inbound_interface_index)): + and self._rpc != self._upstream_interface_state.get(self.inbound_interface_index)): # tree is Active print("PARA ACTIVE") self._tree_state.transition_to_active(self) diff --git a/hpimdm/tree/hpim_globals.py b/hpimdm/tree/hpim_globals.py index b36b354..200c6c0 100644 --- a/hpimdm/tree/hpim_globals.py +++ b/hpimdm/tree/hpim_globals.py @@ -22,7 +22,7 @@ # Control fragmentation of Sync messages # Number of trees per Sync message -# If zero, use information from MTU of interface, otherwise only include a positive given number of trees per Sync message +# If zero use information from MTU of interface, otherwise only include a positive given number of trees per Sync message SYNC_FRAGMENTATION_MSG = 0 @@ -36,11 +36,20 @@ SYNC_RETRANSMISSION_TIME = 3 -# When an AW loses an assert and becomes AL, it can hold its forwarding state for a given ammount of time to prevent -# the loss of data packes (the new AW may not be receiving multicast tree from its parent yet causing the interest -# signaling to be propageted upwards the tree). +# When an AW loses an assert and becomes AL, it can hold its forwarding state for a given amount of time to prevent +# the loss of data packets (the new AW may not be receiving multicast tree from its parent yet causing the interest +# signaling to be propagated upwards the tree). # If enabled this prevents loss of data packets after the AW is replaced, but duplications may occur for a small # amount of time (the AW and the AL may both forwarding packets at the same time during AL_HOLD_FORWARDING_STATE_TIME) # If disabled the duplication of data packets does not occur but loss of packets may occur AL_HOLD_FORWARDING_STATE_ENABLED = True AL_HOLD_FORWARDING_STATE_TIME = 2 + + +# MULTIPLE TABLES SUPPORT +# Define which unicast routing table to be used for RPF checks and to get route metric information +# Default unicast routing table is 254 +UNICAST_TABLE_ID = 254 +# Define which multicast routing table to be used for setting multicast trees +# Default multicast routing table is 0 +MULTICAST_TABLE_ID = 0 diff --git a/hpimdm/tree/tree_if_root.py b/hpimdm/tree/tree_if_root.py index acd37df..4d5fa2f 100644 --- a/hpimdm/tree/tree_if_root.py +++ b/hpimdm/tree/tree_if_root.py @@ -58,7 +58,7 @@ def socket_recv(self): while self.socket_is_enabled: try: self.socket_pkt.recvfrom(0) - print("PACOTE DADOS RECEBIDO") + print("DATA RECEIVED") self.recv_data_msg() except: traceback.print_exc() diff --git a/hpimdm/tree/tree_if_root_originator.py b/hpimdm/tree/tree_if_root_originator.py index 0b93c06..beaa96e 100644 --- a/hpimdm/tree/tree_if_root_originator.py +++ b/hpimdm/tree/tree_if_root_originator.py @@ -43,12 +43,12 @@ def socket_recv(self): while self.socket_is_enabled: try: self.socket_pkt.recvfrom(0) - print("PACOTE DADOS RECEBIDO") + print("DATA RECEIVED") self.recv_data_msg() except: traceback.print_exc() continue - print("SAIU DO SOCKET") + print("EXIT SOCKET") ########################################## # Set timers diff --git a/setup.py b/setup.py index db17c80..9a42a45 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ long_description=open("README.md", "r").read(), long_description_content_type="text/markdown", keywords="HPIM-DM Multicast Routing Protocol Dense-Mode Router IPv4 IPv6", - version="1.3.2", + version="1.3.3.1", url="http://github.com/pedrofran12/hpim_dm", author="Pedro Oliveira", author_email="pedro.francisco.oliveira@tecnico.ulisboa.pt",