Commit 43fc51da authored by Pedro Oliveira's avatar Pedro Oliveira

Fix messages, interfaces added in kernel, graft dst ip address, return ip address type str

parent 9290b913
......@@ -14,7 +14,7 @@ class InterfaceIGMP(object):
PACKET_MR_ALLMULTI = 2
def __init__(self, interface_name: str):
def __init__(self, interface_name: str, vif_index:int):
# RECEIVE SOCKET
rcv_s = socket.socket(socket.PF_PACKET, socket.SOCK_RAW, socket.htons(InterfaceIGMP.ETH_P_IP))
......@@ -39,6 +39,9 @@ class InterfaceIGMP(object):
from igmp.RouterState import RouterState
self.interface_state = RouterState(self)
# virtual interface index for the multicast routing table
self.vif_index = vif_index
# run receive method in background
receive_thread = threading.Thread(target=self.receive)
receive_thread.daemon = True
......@@ -47,6 +50,11 @@ class InterfaceIGMP(object):
def get_ip(self):
return netifaces.ifaddresses(self.interface_name)[netifaces.AF_INET][0]['addr']
@property
def ip_interface(self):
return self.get_ip()
def send(self, data: bytes, address: str="224.0.0.1"):
if self.interface_enabled:
self.send_socket.sendto(data, (address, 0))
......
......@@ -20,7 +20,7 @@ class InterfacePim(Interface):
MAX_TRIGGERED_HELLO_PERIOD = 5
def __init__(self, interface_name: str):
def __init__(self, interface_name: str, vif_index:int):
super().__init__(interface_name)
# generation id
......@@ -50,12 +50,18 @@ class InterfacePim(Interface):
self.neighbors = {}
self.neighbors_lock = RWLockWrite()
# virtual interface index for the multicast routing table
self.vif_index = vif_index
# run receive method in background
receive_thread = threading.Thread(target=self.receive)
receive_thread.daemon = True
receive_thread.start()
def create_virtual_interface(self):
self.vif_index = Main.kernel.create_virtual_interface(ip_interface=self.ip_interface, interface_name=self.interface_name)
def receive(self):
while self.is_enabled():
try:
......@@ -66,16 +72,6 @@ class InterfacePim(Interface):
traceback.print_exc()
continue
"""
while self.interface_enabled:
(raw_packet, (ip, _)) = self.socket.recvfrom(256 * 1024)
if raw_packet:
packet = ReceivedPacket(raw_packet, self)
Main.protocols[packet.payload.get_pim_type()].receive_handle(packet) # TODO: perceber se existe melhor maneira de fazer isto
except Exception:
traceback.print_exc()
continue
"""
def send(self, data: bytes, group_ip: str=MCAST_GRP):
super().send(data=data, group_ip=group_ip)
......@@ -107,6 +103,7 @@ class InterfacePim(Interface):
self.send(packet.bytes())
super().remove()
Main.kernel.remove_virtual_interface(self.ip_interface)
def add_neighbor(self, ip, random_number, hello_hold_time):
......
This diff is collapsed.
......@@ -16,39 +16,45 @@ igmp = None
def add_interface(interface_name, pim=False, igmp=False):
if pim is True and interface_name not in interfaces:
interface = InterfacePim(interface_name)
interfaces[interface_name] = interface
if igmp is True and interface_name not in igmp_interfaces:
interface = InterfaceIGMP(interface_name)
igmp_interfaces[interface_name] = interface
#if pim is True and interface_name not in interfaces:
# interface = InterfacePim(interface_name)
# interfaces[interface_name] = interface
# interface.create_virtual_interface()
#if igmp is True and interface_name not in igmp_interfaces:
# interface = InterfaceIGMP(interface_name)
# igmp_interfaces[interface_name] = interface
kernel.create_interface(interface_name=interface_name, pim=pim, igmp=igmp)
#if pim:
# interfaces[interface_name] = kernel.pim_interface[interface_name]
#if igmp:
# igmp_interfaces[interface_name] = kernel.igmp_interface[interface_name]
def remove_interface(interface_name, pim=False, igmp=False):
if pim is True and ((interface_name in interfaces) or interface_name == "*"):
if interface_name == "*":
interface_name_list = list(interfaces.keys())
else:
interface_name_list = [interface_name]
for if_name in interface_name_list:
interface_obj = interfaces.pop(if_name)
interface_obj.remove()
#interfaces[if_name].remove()
#del interfaces[if_name]
print("removido interface")
print(interfaces)
if igmp is True and ((interface_name in igmp_interfaces) or interface_name == "*"):
if interface_name == "*":
interface_name_list = list(igmp_interfaces.keys())
else:
interface_name_list = [interface_name]
for if_name in interface_name_list:
igmp_interfaces[if_name].remove()
del igmp_interfaces[if_name]
print("removido interface")
print(igmp_interfaces)
#if pim is True and ((interface_name in interfaces) or interface_name == "*"):
# if interface_name == "*":
# interface_name_list = list(interfaces.keys())
# else:
# interface_name_list = [interface_name]
# for if_name in interface_name_list:
# interface_obj = interfaces.pop(if_name)
# interface_obj.remove()
# #interfaces[if_name].remove()
# #del interfaces[if_name]
# print("removido interface")
# print(interfaces)
#if igmp is True and ((interface_name in igmp_interfaces) or interface_name == "*"):
# if interface_name == "*":
# interface_name_list = list(igmp_interfaces.keys())
# else:
# interface_name_list = [interface_name]
# for if_name in interface_name_list:
# igmp_interfaces[if_name].remove()
# del igmp_interfaces[if_name]
# print("removido interface")
# print(igmp_interfaces)
kernel.remove_interface(interface_name, pim=pim, igmp=igmp)
def add_protocol(protocol_number, protocol_obj):
global protocols
......@@ -199,3 +205,8 @@ def main():
global u
u = UnicastRouting.UnicastRouting()
global interfaces
global igmp_interfaces
interfaces = kernel.pim_interface
igmp_interfaces = kernel.igmp_interface
......@@ -39,7 +39,7 @@ class KernelEntry:
# (S,G) starts IG state
self._was_olist_null = None
self._was_olist_null = False
# todo
#self._rpf_is_origin = False
......@@ -49,7 +49,7 @@ class KernelEntry:
self.inbound_interface_index = Main.kernel.vif_dic[self.check_rpf()]
Main.kernel.flood(source_ip, group_ip, self.inbound_interface_index)
#Main.kernel.flood(source_ip, group_ip, self.inbound_interface_index)
self.interface_state = {} # type: Dict[int, TreeInterface]
......@@ -68,7 +68,8 @@ class KernelEntry:
self._lock_test2 = RLock()
self.CHANGE_STATE_LOCK = RLock()
#self._was_olist_null = self.is_olist_null()
self.change()
self.evaluate_olist_change()
print('Tree created')
#self._liveliness_timer = None
#if self.is_originater():
......@@ -122,7 +123,8 @@ class KernelEntry:
def recv_graft_msg(self, index, packet):
print("recv graft msg")
upstream_neighbor_address = packet.payload.payload.upstream_neighbor_address
self.interface_state[index].recv_graft_msg(upstream_neighbor_address)
source_ip = packet.ip_header.ip_src
self.interface_state[index].recv_graft_msg(upstream_neighbor_address, source_ip)
def recv_graft_ack_msg(self, index, packet):
print("recv graft ack msg")
......@@ -218,3 +220,24 @@ class KernelEntry:
state.delete()
Main.kernel.remove_multicast_route(self)
######################################
# Interface change
#######################################
def new_interface(self, index):
with self.CHANGE_STATE_LOCK:
self.interface_state[index] = TreeInterfaceDownstream(self, index)
self.change()
self.evaluate_olist_change()
def remove_interface(self, index):
with self.CHANGE_STATE_LOCK:
#check if removed interface is root interface
if self.inbound_interface_index == index:
self.delete()
else:
self.interface_state[index].delete()
del self.interface_state[index]
self.change()
self.evaluate_olist_change()
......@@ -105,10 +105,9 @@ class AssertStateABC(metaclass=ABCMeta):
def _sendAssert_setAT(interface: "TreeInterfaceDownstream"):
interface.send_assert()
#interface.assert_timer.set_timer(pim_globals.ASSERT_TIME)
interface.set_assert_timer(pim_globals.ASSERT_TIME)
interface.send_assert()
#interface.assert_timer.reset()
@staticmethod
......@@ -136,12 +135,12 @@ class NoInfoState(AssertStateABC):
"""
@type interface: TreeInterface
"""
NoInfoState._sendAssert_setAT(interface)
interface.set_assert_state(AssertState.Winner)
#interface.assert_winner_metric = interface.assert_metric
interface.set_assert_winner_metric(interface.my_assert_metric())
NoInfoState._sendAssert_setAT(interface)
#interface.assert_winner_metric = interface.assert_metric
print('receivedDataFromDownstreamIf, NI -> W')
@staticmethod
......@@ -150,12 +149,12 @@ class NoInfoState(AssertStateABC):
@staticmethod
def receivedInferiorMetricFromNonWinner_couldAssertIsTrue(interface: "TreeInterfaceDownstream"):
NoInfoState._sendAssert_setAT(interface)
interface.set_assert_state(AssertState.Winner)
interface.set_assert_winner_metric(interface.my_assert_metric())
NoInfoState._sendAssert_setAT(interface)
#interface.assert_state = AssertState.Winner
interface.set_assert_state(AssertState.Winner)
#interface.assert_winner_metric = interface.assert_metric
interface.set_assert_winner_metric(interface.my_assert_metric())
print(
'receivedInferiorMetricFromNonWinner_couldAssertIsTrue, NI -> W')
......@@ -174,12 +173,12 @@ class NoInfoState(AssertStateABC):
assert_timer_value = state_refresh_interval*3
interface.set_assert_timer(assert_timer_value)
interface.set_assert_winner_metric(better_metric)
interface.set_assert_state(AssertState.Loser)
#interface.assert_timer.reset()
#interface.assert_state = AssertState.Loser
interface.set_assert_state(AssertState.Loser)
#interface.assert_winner_metric = better_metric
interface.set_assert_winner_metric(better_metric)
# todo MUST also multicast a Prune(S,G) to the Assert winner <- TO THE colocar endereco do winner
if interface.could_assert():
......
......@@ -25,7 +25,7 @@ class DownstreamStateABS(metaclass=ABCMeta):
raise NotImplementedError()
@abstractstaticmethod
def receivedGraft(interface: "TreeInterfaceDownstream"):
def receivedGraft(interface: "TreeInterfaceDownstream", source_ip):
"""
Receive Graft(S,G)
......@@ -113,7 +113,7 @@ class NoInfo(DownstreamStateABS):
print("receivedJoin, NI -> NI")
@staticmethod
def receivedGraft(interface: "TreeInterfaceDownstream"):
def receivedGraft(interface: "TreeInterfaceDownstream", source_ip):
"""
Receive Graft(S,G)
......@@ -122,7 +122,7 @@ class NoInfo(DownstreamStateABS):
# todo why pt stop???!!!
#interface.get_pt().stop()
interface.send_graft_ack()
interface.send_graft_ack(source_ip)
print('receivedGraft, NI -> NI')
......@@ -205,7 +205,7 @@ class PrunePending(DownstreamStateABS):
print('receivedJoin, PP -> NI')
@staticmethod
def receivedGraft(interface: "TreeInterfaceDownstream"):
def receivedGraft(interface: "TreeInterfaceDownstream", source_ip):
"""
Receive Graft(S,G)
......@@ -216,7 +216,7 @@ class PrunePending(DownstreamStateABS):
interface.clear_prune_pending_timer()
interface.set_prune_state(DownstreamState.NoInfo)
interface.send_graft_ack()
interface.send_graft_ack(source_ip)
print('receivedGraft, PP -> NI')
......@@ -321,7 +321,7 @@ class Pruned(DownstreamStateABS):
print('receivedPrune, P -> NI')
@staticmethod
def receivedGraft(interface: "TreeInterfaceDownstream"):
def receivedGraft(interface: "TreeInterfaceDownstream", source_ip):
"""
Receive Graft(S,G)
......@@ -330,7 +330,7 @@ class Pruned(DownstreamStateABS):
#interface.get_pt().stop()
interface.clear_prune_timer()
interface.set_prune_state(DownstreamState.NoInfo)
interface.send_graft_ack()
interface.send_graft_ack(source_ip)
print('receivedGraft, P -> NI')
......
......@@ -74,3 +74,7 @@ class AssertMetric(object):
value = ipaddress.ip_address(value)
self._ip_address = value
def get_ip(self):
return str(self._ip_address)
......@@ -103,26 +103,31 @@ class TreeInterfaceDownstream(TreeInterface):
def recv_prune_msg(self, upstream_neighbor_address, holdtime):
super().recv_prune_msg(upstream_neighbor_address, holdtime)
# set here???
#TODO if upstream_neighbor_address == self.get_ip():
if upstream_neighbor_address == self.get_ip():
self.set_receceived_prune_holdtime(holdtime)
self._prune_state.receivedPrune(self, holdtime)
# Override
def recv_join_msg(self, upstream_neighbor_address):
super().recv_join_msg(upstream_neighbor_address)
if upstream_neighbor_address == self.get_ip():
self._prune_state.receivedJoin(self)
# Override
def recv_graft_msg(self, upstream_neighbor_address):
super().recv_graft_msg(upstream_neighbor_address)
self._prune_state.receivedGraft(self)
def recv_graft_msg(self, upstream_neighbor_address, source_ip):
print("GRAFT!!!")
super().recv_graft_msg(upstream_neighbor_address, source_ip)
if upstream_neighbor_address == self.get_ip():
self._prune_state.receivedGraft(self, source_ip)
# Override
def is_forwarding(self):
return ((len(self.get_interface().neighbors) >= 1 and not self.is_pruned()) or self.igmp_has_members()) and not self.lost_assert()
# todo wtf is boundary??!!
#return self._assert_state == AssertState.Winner and self.is_in_group()
def is_pruned(self):
......@@ -138,7 +143,9 @@ class TreeInterfaceDownstream(TreeInterface):
# Override
def delete(self):
TreeInterface.delete(self)
#self._get_dipt().cancel()
self.clear_assert_timer()
self.clear_prune_timer()
self.clear_prune_pending_timer()
def get_metric(self):
return AssertMetric.spt_assert_metric(self)
......
......@@ -118,6 +118,7 @@ class TreeInterfaceUpstream(TreeInterface):
self._graft_prune_state.seePrune(self)
def recv_graft_ack_msg(self):
print("GRAFT ACK!!!")
# todo check rpf nbr
self._graft_prune_state.recvGraftAckFromRPFnbr(self)
......@@ -146,6 +147,10 @@ class TreeInterfaceUpstream(TreeInterface):
#Override
def delete(self):
super().delete()
self.clear_graft_retry_timer()
self.clear_assert_timer()
self.clear_prune_limit_timer()
self.clear_override_timer()
def is_downstream(self):
return False
......
......@@ -160,7 +160,7 @@ class TreeInterface(metaclass=ABCMeta):
if upstream_neighbor_address == self.get_ip():
self._assert_state.receivedPruneOrJoinOrGraft(self)
def recv_graft_msg(self, upstream_neighbor_address):
def recv_graft_msg(self, upstream_neighbor_address, source_ip):
if upstream_neighbor_address == self.get_ip():
self._assert_state.receivedPruneOrJoinOrGraft(self)
......@@ -186,30 +186,33 @@ class TreeInterface(metaclass=ABCMeta):
(source, group) = self.get_tree_id()
# todo self.get_rpf_()
ph = PacketPimGraft("10.0.0.13")
ip_dst = self.get_neighbor_RPF()
ph = PacketPimGraft(ip_dst)
ph.add_multicast_group(PacketPimJoinPruneMulticastGroup(group, joined_src_addresses=[source]))
pckt = Packet(payload=PacketPimHeader(ph))
self.get_interface().send(pckt.bytes())
self.get_interface().send(pckt.bytes(), ip_dst)
#msg = GraftMsg(self.get_tree().tree_id, self.get_rpf_())
#self.pim_if.send_mcast(msg)
except:
traceback.print_exc()
return
def send_graft_ack(self):
def send_graft_ack(self, ip_sender):
print("send graft ack")
try:
(source, group) = self.get_tree_id()
# todo endereco?!!
ph = PacketPimGraftAck("10.0.0.13")
ph = PacketPimGraftAck(ip_sender)
ph.add_multicast_group(PacketPimJoinPruneMulticastGroup(group, joined_src_addresses=[source]))
pckt = Packet(payload=PacketPimHeader(ph))
self.get_interface().send(pckt.bytes())
self.get_interface().send(pckt.bytes(), ip_sender)
#msg = GraftAckMsg(self.get_tree().tree_id, self.get_node())
#self.pim_if.send_mcast(msg)
except:
traceback.print_exc()
return
......@@ -224,13 +227,14 @@ class TreeInterface(metaclass=ABCMeta):
(source, group) = self.get_tree_id()
# todo help ip of ph
#ph = PacketPimJoinPrune("123.123.123.123", 210)
ph = PacketPimJoinPrune("123.123.123.123", holdtime)
ph = PacketPimJoinPrune(self.get_neighbor_RPF(), holdtime)
ph.add_multicast_group(PacketPimJoinPruneMulticastGroup(group, pruned_src_addresses=[source]))
pckt = Packet(payload=PacketPimHeader(ph))
self.get_interface().send(pckt.bytes())
print('sent prune msg')
except:
traceback.print_exc()
return
......@@ -246,6 +250,7 @@ class TreeInterface(metaclass=ABCMeta):
self.get_interface().send(pckt.bytes())
print("send prune echo")
except:
traceback.print_exc()
return
# todo
#msg = PruneMsg(self.get_tree().tree_id,
......@@ -258,7 +263,7 @@ class TreeInterface(metaclass=ABCMeta):
try:
(source, group) = self.get_tree_id()
# todo help ip of ph
ph = PacketPimJoinPrune("123.123.123.123", 210)
ph = PacketPimJoinPrune(self.get_neighbor_RPF(), 210)
ph.add_multicast_group(PacketPimJoinPruneMulticastGroup(group, joined_src_addresses=[source]))
pckt = Packet(payload=PacketPimHeader(ph))
......@@ -266,6 +271,7 @@ class TreeInterface(metaclass=ABCMeta):
#msg = JoinMsg(self.get_tree().tree_id, self.get_rpf_())
#self.pim_if.send_mcast(msg)
except:
traceback.print_exc()
return
......@@ -280,6 +286,7 @@ class TreeInterface(metaclass=ABCMeta):
self.get_interface().send(pckt.bytes())
except:
traceback.print_exc()
return
......@@ -295,6 +302,7 @@ class TreeInterface(metaclass=ABCMeta):
self.get_interface().send(pckt.bytes())
except:
traceback.print_exc()
return
#msg = AssertMsg.new_assert_cancel(self.tree_id)
#self.pim_if.send_mcast(msg)
......@@ -388,8 +396,8 @@ class TreeInterface(metaclass=ABCMeta):
raise NotImplementedError()
def get_rpf_(self):
return self.get_neighbor_RPF()
#def get_rpf_(self):
# return self.get_neighbor_RPF()
# obtain ip of RPF'(S)
......@@ -397,11 +405,14 @@ class TreeInterface(metaclass=ABCMeta):
'''
RPF'(S)
'''
if not self.is_assert_winner():
return self._assert_winner_ip
if self.i_am_assert_loser():
return self._assert_winner_metric.get_ip()
else:
return self._kernel_entry.rpf_node
def i_am_assert_loser(self):
return self._assert_state == AssertState.Loser
def is_assert_winner(self):
return not self.is_downstream() and not self._assert_state == AssertState.Loser
......
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