def _build_ondemand_links(self, adj_list, transition_adj_list, request_list): ond = {} # add existing on demand links existing = transition_adj_list.edges_bytype(["CETypeOnDemand"]) for peer_id, ce in existing.items(): if ce.edge_state in ("CEStateInitialized", "CEStatePreAuth", "CEStateAuthorized", \ "CEStateCreated", "CEStateConnected") and peer_id not in adj_list: ond[peer_id] = ConnectionEdge(peer_id, ce.edge_id, ce.edge_type) task_rmv = [] for task in request_list: peer_id = task["PeerId"] op = task["Operation"] if op == "ADD": task_rmv.append(task) if peer_id in self._peers and (peer_id not in adj_list or peer_id not in transition_adj_list): ce = ConnectionEdge(peer_id, edge_type="CETypeOnDemand") ond[peer_id] = ce elif op == "REMOVE": ond.pop(peer_id, None) if peer_id not in adj_list: # only clear the task after the tunnel has been removed by NetworkBuilder task_rmv.append(task) for peer_id in ond: if peer_id not in adj_list: adj_list[peer_id] = ond[peer_id] for task in task_rmv: request_list.remove(task)
def negotiate_incoming_edge(self, edge_req): """ Role B1 """ self._top.log("LOG_DEBUG", "Rcvd EdgeRequest=%s", str(edge_req)) edge_resp = None peer_id = edge_req.initiator_id if peer_id in self._current_adj_list: edge_resp = self._resolve_request_collision(edge_req) elif edge_req.edge_type == "CETypeSuccessor": edge_resp = EdgeResponse(is_accepted=True, data="Successor edge permitted") elif edge_req.edge_type == "CETypeEnforced": edge_resp = EdgeResponse(is_accepted=True, data="Enforced edge permitted") elif edge_req.edge_type == "CETypeOnDemand": edge_resp = EdgeResponse(is_accepted=True, data="On-demand edge permitted") elif not self._current_adj_list.is_threshold_ildl(): edge_resp = EdgeResponse(is_accepted=True, data="Any edge permitted") else: edge_resp = EdgeResponse(is_accepted=False, data="E5 - Too many existing edges.") if edge_resp.is_accepted and edge_resp.data[:2] != "E0": et = ng.transpose_edge_type(edge_req.edge_type) ce = ConnectionEdge(peer_id=peer_id, edge_id=edge_req.edge_id, edge_type=et) ce.edge_state = "CEStatePreAuth" self._negotiated_edges[peer_id] = ce self._top.log("LOG_DEBUG", "New CE=%s added to negotiated_edges=%s", str(ce), str(self._negotiated_edges)) return edge_resp
def _build_long_dist_links(self, adj_list, transition_adj_list): # Preserve existing incoming ldl # handled in net builder #ldlnks = transition_adj_list.edges_bytype(["CETypeILongDistance"]) #for peer_id, ce in ldlnks.items(): # if ce.edge_state in ("CEStateInitialized", "CEStateCreated", "CEStateConnected") and \ # peer_id not in adj_list: # adj_list[peer_id] = ConnectionEdge(peer_id, ce.edge_id, ce.edge_type) # evaluate existing ldl ldlnks = {} if not self._relink: ldlnks = transition_adj_list.edges_bytype(["CETypeLongDistance"]) num_existing_ldl = 0 for peer_id, ce in ldlnks.items(): if ce.edge_state in ["CEStateConnected"] and \ peer_id not in adj_list and not self.is_too_close(ce.peer_id): adj_list[peer_id] = ConnectionEdge(peer_id, ce.edge_id, ce.edge_type) num_existing_ldl += 1 if num_existing_ldl >= self._max_ldl_cnt: return num_ldl = self._max_ldl_cnt - num_existing_ldl ldl = self._get_long_dist_links(num_ldl) for peer_id in ldl: if peer_id not in adj_list: ce = ConnectionEdge(peer_id, edge_type="CETypeLongDistance") adj_list.add_conn_edge(ce)
def build_adj_list_ata(self,): """ Generates a new adjacency list from the list of available peers """ adj_list = ConnEdgeAdjacenctList(self.overlay_id, self._node_id, self._max_successors, self._max_ldl_cnt, self._max_ond) for peer_id in self._peers: if self._enforced and peer_id in self._enforced: ce = ConnectionEdge(peer_id) ce.edge_type = "CETypeEnforced" adj_list.add_connection_edge(ce) elif not self._manual_topo and self._node_id < peer_id: ce = ConnectionEdge(peer_id) ce.edge_type = "CETypeSuccessor" adj_list.add_connection_edge(ce) return adj_list
def _build_successors(self, adj_list): successors = self._get_successors() for peer_id in successors: #exclude if peer was previously added as another edge type if peer_id not in adj_list.conn_edges: ce = ConnectionEdge(peer_id, "CETypeSuccessor") adj_list.add_connection_edge(ce)
def on_connection_update(self, connection_event): """ Updates the connection edge's current state based on the provided event. This is the completion for a create or remove connection request to Link Manager. """ peer_id = connection_event["PeerId"] link_id = connection_event["LinkId"] overlay_id = connection_event["OverlayId"] with self._lock: if connection_event["UpdateType"] == "CREATING": conn_edge = self._current_adj_list.conn_edges.get( peer_id, None) if not conn_edge: # this happens when the neighboring peer initiates the connection bootstrap self._refresh_in_progress += 1 conn_edge = ConnectionEdge(peer_id, "CETypePredecessor") self._current_adj_list.conn_edges[peer_id] = conn_edge conn_edge.edge_state = "CEStateCreated" conn_edge.link_id = link_id elif connection_event["UpdateType"] == "REMOVED": self._current_adj_list.conn_edges.pop(peer_id, None) self._refresh_in_progress -= 1 elif connection_event["UpdateType"] == "CONNECTED": self._current_adj_list.conn_edges[ peer_id].edge_state = "CEStateConnected" self._current_adj_list.conn_edges[peer_id].connected_time = \ connection_event["ConnectedTimestamp"] self._refresh_in_progress -= 1 elif connection_event["UpdateType"] == "DISCONNECTED": # the local topology did not request removal of the connection self._top.top_log( "CEStateDisconnected event recvd peer_id: {0}, link_id: {1}" .format(peer_id, link_id)) self._current_adj_list.conn_edges[ peer_id].edge_state = "CEStateDisconnected" self._refresh_in_progress += 1 self._top.top_remove_edge(overlay_id, peer_id) elif connection_event["UpdateType"] == "RemoveEdgeFailed": # leave the node in the adj list and marked for removal to be retried. self._refresh_in_progress -= 1 else: self._top.top_log( "Logger", "LOG_WARNING", "Invalid UpdateType specified for connection update")
def on_connection_update(self, connection_event): """ Updates the connection edge's current state based on the provided event. This is the completion for a create or remove connection request to Link Manager. """ peer_id = connection_event["PeerId"] link_id = connection_event["LinkId"] overlay_id = connection_event["OverlayId"] with self._lock: if connection_event["UpdateType"] == "CREATING": conn_edge = self._current_edges.conn_edges.get(peer_id, None) if not conn_edge: # this happens when the neighboring peer initiates the connection bootstrap self._refresh_in_progress = self._refresh_in_progress + 1 conn_edge = ConnectionEdge(peer_id) self._current_edges.conn_edges[peer_id] = conn_edge conn_edge.type = "CETypePredecessor" conn_edge.state = "CEStateCreated" conn_edge.link_id = link_id elif connection_event["UpdateType"] == "REMOVED": self._current_edges.conn_edges.pop(peer_id, None) self._refresh_in_progress = self._refresh_in_progress - 1 elif connection_event["UpdateType"] == "CONNECTED": self._current_edges.conn_edges[ peer_id].state = "CEStateConnected" self._current_edges.conn_edges[peer_id].connected_time = \ connection_event["ConnectedTimestamp"] self._refresh_in_progress = self._refresh_in_progress - 1 elif connection_event["UpdateType"] == "DISCONNECTED": # this branch is taken when the local node did not explicitly remove the connection self._top.top_log( "CEStateDisconnected event recvd peer_id: {0}, link_id: {1}" .format(peer_id, link_id)) self._current_edges.conn_edges[ peer_id].state = "CEStateDisconnected" self._refresh_in_progress = self._refresh_in_progress + 1 self._top.top_remove_edge(overlay_id, peer_id)
def _build_successors(self, adj_list, transition_adj_list): num_ideal_conn_succ = 0 successors = self._get_successors() suc_ces = transition_adj_list.filter([("CETypeSuccessor", "CEStateConnected")]) # add the ideal successors to the new adj list for peer_id in successors: if peer_id not in adj_list: adj_list[peer_id] = ConnectionEdge(peer_id, edge_type="CETypeSuccessor") if peer_id in suc_ces: # this is an ideal succ that was previously connected num_ideal_conn_succ += 1 del suc_ces[peer_id] # do not remove the existing successor until the new one is connected for peer_id in suc_ces: # these are to be replaced when the ideal ones are in connected state if num_ideal_conn_succ < self._max_successors: # not an ideal successor but keep until better succ is connected adj_list[peer_id] = ConnectionEdge(peer_id, edge_type="CETypeSuccessor") num_ideal_conn_succ += 1 else: break # consider selecting the best of these
def _build_long_dist_links(self, adj_list, transition_adj_list): # Add potential long distance link candidates to the adjacency list up to the difference # of the max link and existing links existing_ldlnks = transition_adj_list.get_edges("CETypeLongDistance") existing_ldlnk_cnt = len(existing_ldlnks) adj_list.conn_edges.update(existing_ldlnks) if self._max_ldl_cnt - existing_ldlnk_cnt <= 0: return ldl = self._get_long_dist_links() for peer_id in ldl: if self._max_ldl_cnt - existing_ldlnk_cnt > 0: if peer_id not in adj_list.conn_edges: ce = ConnectionEdge(peer_id, "CETypeLongDistance") adj_list.add_connection_edge(ce) existing_ldlnk_cnt += 1 else: return
def build_adj_list(self, ): """ Generates a new adjacency list from the list of available peers """ adj_list = ConnEdgeAdjacenctList(self.overlay_id, self._node_id) for peer_id in self._peers: if self._enforced and peer_id in self._enforced: ce = ConnectionEdge(peer_id) ce.type = "CETypeEnforced" adj_list.conn_edges[peer_id] = ce elif not self._manual_topo and self._node_id < peer_id: ce = ConnectionEdge(peer_id) ce.type = "CETypeSuccessor" adj_list.conn_edges[peer_id] = ce return adj_list
def build_adj_list_ata(self, ): """ Generates a new adjacency list from the list of available peers """ adj_list = ConnEdgeAdjacenctList(self.overlay_id, self._node_id, self._max_successors, self._max_ldl_cnt, self._max_ond) for peer_id in self._peers: if self._enforced_edges and peer_id in self._enforced_edges: ce = ConnectionEdge(peer_id) ce.edge_type = "CETypeEnforced" adj_list.add_conn_edge(ce) elif not self._manual_topo and self._node_id < peer_id: ce = ConnectionEdge(peer_id) ce.edge_type = "CETypeSuccessor" adj_list.add_conn_edge(ce) return adj_list
def _build_enforced(self, adj_list): for peer_id in self._enforced_edges: ce = ConnectionEdge(peer_id, edge_type="CETypeEnforced") adj_list.add_conn_edge(ce)