def new_neighbor_or_adjacency_reset(neighbor): neighbor.set_sync_state(Slave) neighbor.start_snapshot() # Remove all info from neighbor (if already knew it) neighbor.tree_interest_state.clear() neighbor.tree_metric_state.clear() neighbor.last_sequence_number.clear() neighbor.current_sync_sn = 0 neighbor.neighbor_snapshot_sn = 0 neighbor.checkpoint_sn = 0 # my_snapshot_mrt = neighbor.my_snapshot_multicast_routing_table[ 0:neighbor.sync_fragmentation] my_more_bit = len(neighbor.my_snapshot_multicast_routing_table) > 0 my_snapshot_sn = neighbor.my_snapshot_sequencer pkt_s = PacketHPIMSync(my_snapshot_sn, 0, sync_sn=neighbor.current_sync_sn, upstream_trees=my_snapshot_mrt, master_flag=True, more_flag=my_more_bit, neighbor_boot_time=neighbor.time_of_boot) pkt = Packet( payload=PacketHPIMHeader(pkt_s, neighbor.my_snapshot_boot_time)) neighbor.contact_interface.send(pkt, neighbor.ip) neighbor.set_sync_timer() neighbor.set_hello_hold_time(DEFAULT_HELLO_HOLD_TIME_DURING_SYNC)
def sync_timer_expires(neighbor): my_snapshot_mrt = neighbor.my_snapshot_multicast_routing_table[ neighbor.current_sync_sn * neighbor.sync_fragmentation:(neighbor.current_sync_sn + 1) * neighbor.sync_fragmentation] my_more_bit = len( neighbor.my_snapshot_multicast_routing_table ) > neighbor.current_sync_sn * neighbor.sync_fragmentation my_snapshot_sn = neighbor.my_snapshot_sequencer neighbor_sn = neighbor.neighbor_snapshot_sn pkt_s = PacketHPIMSync(my_snapshot_sn, neighbor_sn, sync_sn=neighbor.current_sync_sn, upstream_trees=my_snapshot_mrt, master_flag=True, more_flag=my_more_bit, neighbor_boot_time=neighbor.time_of_boot) if not my_more_bit: pkt_s.add_hello_option( PacketHPIMHelloHoldtime(holdtime=4 * HELLO_PERIOD)) pkt = Packet( payload=PacketHPIMHeader(pkt_s, neighbor.my_snapshot_boot_time)) neighbor.send(pkt) neighbor.set_sync_timer()
def send(self, data: Packet, group_ip: str=MCAST_GRP): """ Send a new packet destined to group_ip IP """ if self.is_security_enabled(): key = self.get_security_key() data.payload.security_id = self.security_id data.payload.security_length = self.security_len security_value = hmac.new(key, socket.inet_pton(self._get_address_family(), self.get_ip()) + socket.inet_pton(self._get_address_family(), group_ip) + data.bytes(), digestmod=self.hash_function).digest() data.payload.security_value = security_value #if self.drop_packet_type is not None and data.payload.get_pim_type() == self.drop_packet_type: # self.drop_packet_type = None # return super().send(data=data.bytes(), group_ip=group_ip)
def recv_sync(neighbor, tree_state, my_snapshot_sn, neighbor_snapshot_sn, sync_sn, master_bit, more_bit, hello_options): if neighbor.current_sync_sn == 0 and neighbor.neighbor_snapshot_sn == 0: neighbor.neighbor_snapshot_sn = neighbor_snapshot_sn if neighbor.neighbor_snapshot_sn > neighbor_snapshot_sn: return elif neighbor.neighbor_snapshot_sn < neighbor_snapshot_sn: Master.new_neighbor_or_adjacency_reset(neighbor) return if sync_sn != neighbor.current_sync_sn: return if master_bit and (sync_sn > 0 and neighbor.my_snapshot_sequencer == my_snapshot_sn or sync_sn == 0): neighbor.install_tree_state(tree_state) my_snapshot_mrt = neighbor.my_snapshot_multicast_routing_table[ neighbor.current_sync_sn * neighbor.sync_fragmentation:(neighbor.current_sync_sn + 1) * neighbor.sync_fragmentation] my_more_bit = len( neighbor.my_snapshot_multicast_routing_table ) > neighbor.current_sync_sn * neighbor.sync_fragmentation my_snapshot_sn = neighbor.my_snapshot_sequencer neighbor_sn = neighbor.neighbor_snapshot_sn pkt_s = PacketHPIMSync(my_snapshot_sn, neighbor_sn, sync_sn=neighbor.current_sync_sn, upstream_trees=my_snapshot_mrt, master_flag=False, more_flag=my_more_bit, neighbor_boot_time=neighbor.time_of_boot) if not my_more_bit: pkt_s.add_hello_option( PacketHPIMHelloHoldtime(holdtime=4 * HELLO_PERIOD)) pkt = Packet(payload=PacketHPIMHeader( pkt_s, neighbor.my_snapshot_boot_time)) neighbor.send(pkt) if sync_sn > 0 and not more_bit and not my_more_bit: if "HOLDTIME" in hello_options: neighbor.set_hello_hold_time( hello_options["HOLDTIME"].holdtime) else: neighbor.set_hello_hold_time( DEFAULT_HELLO_HOLD_TIME_AFTER_SYNC) neighbor.set_sync_state(Synced) neighbor.clear_sync_timer() del neighbor.my_snapshot_multicast_routing_table[:] else: neighbor.set_hello_hold_time( DEFAULT_HELLO_HOLD_TIME_DURING_SYNC) neighbor.set_sync_timer() neighbor.current_sync_sn += 1
def remove(self): """ Remove this interface Clear all state """ self.hello_timer.cancel() self.hello_timer = None # send pim_hello timeout message pim_payload = PacketHPIMHello() pim_payload.add_option(PacketHPIMHelloHoldtime(holdtime=HELLO_HOLD_TIME_TIMEOUT)) ph = PacketHPIMHeader(pim_payload, boot_time=self.time_of_boot) packet = Packet(payload=ph) self.send(packet) super().remove() for n in self.neighbors.values(): n.remove_neighbor_state() self.neighbors.clear() self.clear_reliable_transmission()
def recv_sync(neighbor, tree_state, my_snapshot_sn, neighbor_snapshot_sn, sync_sn, master_bit, more_bit, hello_options): if neighbor.neighbor_snapshot_sn > neighbor_snapshot_sn: return elif neighbor.neighbor_snapshot_sn < neighbor_snapshot_sn: Synced.new_neighbor_or_adjacency_reset(neighbor) return if sync_sn != neighbor.current_sync_sn: return if master_bit and neighbor.my_snapshot_sequencer == my_snapshot_sn: pkt_s = PacketHPIMSync(my_snapshot_sn, neighbor_snapshot_sn, sync_sn=sync_sn, master_flag=False, more_flag=False, neighbor_boot_time=neighbor.time_of_boot) pkt_s.add_hello_option( PacketHPIMHelloHoldtime(holdtime=4 * HELLO_PERIOD)) pkt = Packet(payload=PacketHPIMHeader( pkt_s, neighbor.my_snapshot_boot_time)) neighbor.send(pkt)
def send_hello(self): """ Send a new Hello message Include in it the HelloHoldTime and CheckpointSN """ self.hello_timer.cancel() pim_payload = PacketHPIMHello() pim_payload.add_option(PacketHPIMHelloHoldtime(holdtime=4 * HELLO_PERIOD)) with self.neighbors_lock: with self.sequencer_lock: with self.reliable_transmission_lock: (bt, checkpoint_sn) = self.get_checkpoint_sn() if bt == self.time_of_boot: pim_payload.add_option(PacketHPIMHelloCheckpointSN(checkpoint_sn)) ph = PacketHPIMHeader(pim_payload, boot_time=self.time_of_boot) packet = Packet(payload=ph) self.send(packet) # reschedule hello_timer self.hello_timer = Timer(HELLO_PERIOD, self.send_hello) self.hello_timer.start()
def create_sync_msg(self, my_boot_time, my_snapshot_sn, neighbor_snapshot_sn, sync_sn, upstream_trees, master_flag, more_flag, neighbor_boot_time): pkt_sync = PacketHPIMSync(my_snapshot_sn, neighbor_snapshot_sn, sync_sn, upstream_trees, master_flag, more_flag, neighbor_boot_time) return Packet(payload=PacketHPIMHeader(pkt_sync, my_boot_time))
def create_ack_msg(self, my_boot_time, sn, source, group, neighbor_boot_time, neighbor_snapshot_sn, my_snapshot_sn): ack = PacketHPIMAck(source_ip=source, group_ip=group, sequence_number=sn, neighbor_boot_time=neighbor_boot_time, neighbor_snapshot_sn=neighbor_snapshot_sn, my_snapshot_sn=my_snapshot_sn) return Packet(payload=PacketHPIMHeader(payload=ack, boot_time=my_boot_time))
def create_no_interest_msg(self, my_boot_time, sn, source, group): ph = PacketHPIMNoInterest(source, group, sn) return Packet(payload=PacketHPIMHeader(payload=ph, boot_time=my_boot_time))
def create_i_am_no_longer_upstream_msg(self, my_boot_time, sn, source, group): ph = PacketHPIMNoLongerUpstream(source, group, sn) return Packet(payload=PacketHPIMHeader(payload=ph, boot_time=my_boot_time))
def create_i_am_upstream_msg(self, my_boot_time, sn, source, group, metric_preference, metric): ph = PacketHPIMUpstream(source, group, metric_preference, metric, sn) return Packet(payload=PacketHPIMHeader(payload=ph, boot_time=my_boot_time))