public ImageStoreData(NodeId nodeId, string name, int width, int height, byte[] data) : this() { this.NodeId = nodeId; this.Name = name; this.Width = width; this.Height = height; this.Data = data; }
public void StartReloadTLSClient(NodeId nodeid, Socket socket, IPEndPoint attacherEndpoint) { // simply call InitReloadTLSClient ReloadSendParameters send_params = new ReloadSendParameters(); send_params.destinationAddress = attacherEndpoint.Address; link.InitReloadTLSClient(send_params, socket, attacherEndpoint); if (send_params.connectionTableEntry != null) { ReloadConnectionTableEntry connectionTableEntry = send_params.connectionTableEntry; //TODO: not nice but does the trick if (send_params.connectionTableEntry.NodeID != null) //TODO: correct? nodeid = send_params.connectionTableEntry.NodeID; } }
public bool isNewNeighbour(NodeId attacher) { if (m_predecessors.Count == 0 && m_successors.Count == 0) return true; List<NodeId> updateList = new List<NodeId>(m_successors); updateList.AddRange(m_predecessors); updateList.Add(attacher); updateList = removeDuplicates(updateList); List<NodeId> newPres = NeighborsFromTotal(updateList, false); List<NodeId> newSuccs = NeighborsFromTotal(updateList, true); if (IsChangedList(m_predecessors, newPres) || IsChangedList(m_successors, newSuccs)) { return true; } return false; }
} // Send public bool NextHopInConnectionTable(NodeId dest_node_id) { return connectionTable.lookupEntry(dest_node_id) == null; }
internal void SetWaitForJoinAnsw(NodeId nodeId, Boolean fTrue) { try { RTableEntry rtable_entry; lock (m_RtTable) { if (nodeId != null && m_RtTable.TryGetValue(nodeId.ToString(), out rtable_entry)) rtable_entry.wait_for_join_answ = fTrue; } } catch (Exception ex) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "SetWaitForJoinAnsw: " + ex.Message); } }
public IEnumerator<ITask> AttachProcedure(Destination dest, NodeId NextHopId, AttachOption attach_option) { ReloadMessage reloadSendMsg; /* 9.5.1 * When a peer needs to Attach to a new peer in its neighbor table, it MUST source-route the Attach request through the peer from which it learned the new peer's Node-ID. Source-routing these requests allows the overlay to recover from instability. */ reloadSendMsg = create_attach_req(dest, (attach_option & AttachOption.forceupdate) != 0); if (dest.type == DestinationType.node) { NodeState nodestate = m_topology.routing_table.GetNodeState(dest.destination_data.node_id); if (nodestate == NodeState.attaching) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("Ignoring redundant Attach for {0}", dest)); yield break; } } Boolean NextHopIsDestination = false; Node NextHopNode = null; if (NextHopId != null) NextHopNode = m_topology.routing_table.GetNode(NextHopId); if (NextHopNode == null) NextHopNode = NextHopToDestination(dest, ref NextHopIsDestination); if (NextHopNode == null) yield break; if (dest.type == DestinationType.node) m_topology.routing_table.SetNodeState(dest.destination_data.node_id, NodeState.attaching); ReloadDialog reloadDialog = null; int RetransmissionTime = ReloadGlobals.RetransmissionTime + ReloadGlobals.MaxTimeToSendPacket; int iRetrans = ReloadGlobals.MaxRetransmissions; while (iRetrans >= 0 && m_ReloadConfig.State < ReloadConfig.RELOAD_State.Shutdown) { try { /* use a new ReloadDialog instance for every usage, Monitor requires it */ reloadDialog = new ReloadDialog(m_ReloadConfig, m_flm, NextHopNode); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("{0} via {1} ==> Dest={2} TransId={3:x16}", RELOAD_MessageCode.Attach_Request.ToString().PadRight(16, ' '), NextHopNode, dest.ToString(), reloadSendMsg.TransactionID)); Arbiter.Activate(m_DispatcherQueue, new IterativeTask<ReloadMessage, ReloadMessageFilter, int>(reloadSendMsg, new ReloadMessageFilter(reloadSendMsg.TransactionID), RetransmissionTime, reloadDialog.Execute)); } catch (Exception ex) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "AttachProcedure: " + ex.Message); yield break; } yield return Arbiter.Receive(false, reloadDialog.Done, done => { }); if (!reloadDialog.Error && reloadDialog.ReceivedMessage != null) { ReloadMessage reloadRcvMsg = reloadDialog.ReceivedMessage; if (dest.type == DestinationType.node) { if (reloadRcvMsg.OriginatorID != dest.destination_data.node_id) { // drop message and retransmit request m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("Received answer from unexpected peer")); reloadRcvMsg = null; } } else if (dest.type == DestinationType.resource) { int suc = m_topology.routing_table.GetSuccessorCount(false); int pre = m_topology.routing_table.GetPredecessorCount(false); if (suc >= 2 && pre >= 2) { // check if resource is mapping to a node in my routing table if (dest.destination_data.ressource_id.ElementOfInterval( m_topology.routing_table.Predecessors[pre - 2], m_topology.routing_table.Successors[suc - 1], true) ) { if (reloadRcvMsg.OriginatorID < m_topology.routing_table.Predecessors[pre - 2] && reloadRcvMsg.OriginatorID > m_topology.routing_table.Successors[suc - 1]) { // drop message and retransmit request m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("Received answer from unexpected peer")); reloadRcvMsg = null; } } } } if (reloadRcvMsg != null) break; } /* If a response has not been received when the timer fires, the request is retransmitted with the same transaction identifier. */ --iRetrans; if (iRetrans >= 0) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_WARNING, String.Format("Retrans {0} SendAttach via {1} TransId={2:x16}", iRetrans, NextHopNode, reloadSendMsg.TransactionID)); m_ReloadConfig.Statistics.IncRetransmission(); } else { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("Failed! SendAttach via {0} TransId={1:x16}", NextHopNode, reloadSendMsg.TransactionID)); m_ReloadConfig.Statistics.IncTransmissionError(); if (dest.destination_data.node_id != null) { //m_topology.routing_table.SetNodeState(dest.destination_data.node_id, NodeState.unknown); m_topology.routing_table.Leave(dest.destination_data.node_id); } } } try { if (reloadDialog != null && !reloadDialog.Error && reloadDialog.ReceivedMessage != null) { /*the SourceNodeID delivered from reloadDialog comes from connection * table and is the last hop of the message */ ReloadMessage reloadRcvMsg = reloadDialog.ReceivedMessage; RELOAD_MessageCode msgCode = reloadRcvMsg.reload_message_body.RELOAD_MsgCode; AttachReqAns answ = (AttachReqAns)reloadRcvMsg.reload_message_body; if (msgCode == RELOAD_MessageCode.Attach_Answer) { /* TKTODO * 1. The response to a message sent to a specific Node-ID MUST have been sent by that Node-ID. 2. The response to a message sent to a Resource-Id MUST have been sent by a Node-ID which is as close to or closer to the target Resource-Id than any node in the requesting node's neighbor table. */ if (answ != null) { Node Originator = new Node(reloadRcvMsg.OriginatorID, answ.ice_candidates); /* An Attach in and of itself does not result in updating the routing * table of either node. * Note: We use the routing table here only for storing ice candidates * for later use, we will not update successor or predecessor list */ m_topology.routing_table.AddNode(Originator); m_topology.routing_table.SetNodeState(Originator.Id, NodeState.attached); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("{0} <== {1} last={2} TransId={3:x16}", msgCode.ToString().PadRight(16, ' '), reloadRcvMsg.OriginatorID, reloadRcvMsg.LastHopNodeId, reloadRcvMsg.TransactionID)); if ((CheckAndSetAdmittingPeer(Originator) && Originator.Id != reloadRcvMsg.LastHopNodeId) || (attach_option & AttachOption.sendping) != 0) { // Send ping to get a physical connection Arbiter.Activate(m_DispatcherQueue, new IterativeTask<Destination, PingOption>(new Destination(Originator.Id), PingOption.direct, SendPing)); } } } else if (msgCode == RELOAD_MessageCode.Error) { if (dest.type == DestinationType.node) { ErrorResponse error = (ErrorResponse)reloadRcvMsg.reload_message_body; if (error != null) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("AttachProcedure: Got Error {0} from {1} deleting {2}", error.ErrorMsg, reloadRcvMsg.OriginatorID, dest.destination_data.node_id)); m_topology.routing_table.Leave(dest.destination_data.node_id); } } } } } catch (Exception ex) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "AttachProcedure: " + ex.Message); if (dest.destination_data.node_id != null) m_topology.routing_table.SetNodeState(dest.destination_data.node_id, NodeState.unknown); } }
/// <summary> /// TASK: Waits for the reception for max rx_timeout milliseconds. Filters if required. /// </summary> /// <param name="rx_filter">The rx_filter.</param> /// <param name="rx_timeout">The rx_timeout.</param> /// <returns></returns> private IEnumerator<ITask> Receive(ReloadMessageFilter rx_filter, int rx_timeout, String messageCode) { m_DispatcherQueue.EnqueueTimer(TimeSpan.FromMilliseconds(rx_timeout), timeouted); m_fError = false; bool fTimeouted = false; //m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TEST, String.Format("Receiver {0} started", rx_filter.transactionID)); /* there are multiple incoming packets possible, if there wasn't a matching packet so far, * wait for it as long there is no timout condition */ while (!fTimeouted && m_ReloadConfig.State < ReloadConfig.RELOAD_State.Exit) { yield return Arbiter.Choice( Arbiter.Receive(false, timeouted, to => { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_WARNING, String.Format("Receiver {0} Rx Timeout after sending {1}", rx_filter.transactionID, messageCode)); fTimeouted = true; }), Arbiter.Receive(false, m_portWaitForRx, trigger => { //m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TEST, String.Format("Receiver {0} released, error is {1}", rx_filter.transactionID, error)); })); if (!fTimeouted && !m_fError) while (m_Queue.Count != 0 && m_ReloadConfig.State < ReloadConfig.RELOAD_State.Exit) { ReloadFLMEventArgs args = (ReloadFLMEventArgs)m_Queue.Dequeue(); if (args == null || args.Message == null) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("Receive: Args == null")); break; } if (args.Eventtype == ReloadFLMEventArgs.ReloadFLMEventTypes.RELOAD_EVENT_RECEIVE_OK) { ReloadMessage reloadMsg = args.Message; if (reloadMsg == null) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("Receive: Dropping invalid packet from {0}", args.ConnectionTableEntry != null ? args.ConnectionTableEntry.NodeID.ToString() : "unknown")); break; } //m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("Receiver {0} Queuecount {1} Transactionid: {2}", rx_filter.transactionID, m_Queue.Count, reloadMsg.TransactionID)); if (reloadMsg.IsFragmented() && reloadMsg.IsSingleFragmentMessage() == false && rx_filter != null && reloadMsg.TransactionID == rx_filter.transactionID) { ReloadMessage reassembledMsg = null; lock (fragmentedMessageBuffer) { reassembledMsg = reloadMsg.ReceiveFragmentedMessage(ref fragmentedMessageBuffer); } if (reassembledMsg == null) //not yet all fragments received => not reassembled { Arbiter.Activate(m_DispatcherQueue, new IterativeTask<ReloadMessageFilter, int, String>(rx_filter, rx_timeout, "", Receive)); m_TimeStart = DateTime.Now; yield break; } else reloadMsg = reassembledMsg; //message reassembled => continue as usual } if (args.ConnectionTableEntry != null) m_SourceNodeID = args.ConnectionTableEntry.NodeID; else m_SourceNodeID = reloadMsg.LastHopNodeId; if (rx_filter != null) { // m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TEST, String.Format("Receiver {0} Checking against {1}", rx_filter.transactionID, reloadMsg.TransactionID)); /* Most important part: Do only accept messages with the same transaction id * this ReloadDialog had been registered to and ignore the rest */ if (reloadMsg.TransactionID == rx_filter.transactionID) { if (!reloadMsg.IsRequest()) { //m_ReceivedMessage = args.Message; m_ReceivedMessage = reloadMsg; //--joscha /* just a trick to get out of the parent loop */ fTimeouted = true; break; } else { /* Our Request looped back to us, module Forwarding is handling this */ if (reloadMsg.reload_message_body.RELOAD_MsgCode == RELOAD_MessageCode.Error) { if (((ErrorResponse)reloadMsg.reload_message_body).ErrorCode == RELOAD_ErrorCode.Error_Not_Found) { // --joscha not found response => don't wait for timeout m_ReceivedMessage = null; /* just a trick to get out of the parent loop */ fTimeouted = true; break; } } } } } else { /* No filter specified, deliver every packet */ //m_ReceivedMessage = args.Message; m_ReceivedMessage = reloadMsg; //--joscha; /* just a trick to get out of the parent loop */ fTimeouted = true; break; } } } } m_Transport.ReloadFLMEventHandler -= OVL_ReloadForwardLinkManagementEventHandler; m_fDone.Post(true); }
// --josch /// <summary> /// Proprietary: Stores the Usage data in a different RELOAD overlay using viaGateWay as gateway /// </summary> /// <param name="ResourceName"></param> /// <param name="kind_data"></param> /// <param name="viaGateWay"></param> /// <returns></returns> public IEnumerator<ITask> Store(string ResourceName, List<StoreKindData> kind_data, NodeId viaGateWay) { if (m_ReloadConfig.IamClient) m_ReloadConfig.StartStoreMobile = DateTime2.Now; else m_ReloadConfig.StartStore = DateTime.Now; ReloadDialog reloadDialog = null; ReloadMessage reloadSendMsg; ResourceId res_id = new ResourceId(ResourceName); //List<StoreKindData> kind_data = new List<StoreKindData>(); Node node = null; if (viaGateWay != null) { //NodeId gateway = new ResourceId(viaGateWay); node = m_topology.routing_table.FindNextHopTo(viaGateWay, true, false); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_USAGE, String.Format("Store {0} as ResID: {1} via Gateway {2}", ResourceName, res_id, viaGateWay)); if (m_ReloadConfig.IamClient && node == null) { node = m_ReloadConfig.AdmittingPeer; } foreach (StoreKindData storeKindData in kind_data) { if (node == null || node.Id == m_ReloadConfig.LocalNodeID) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TOPO, String.Format("Local storage at NodeId {0}", node.Id)); m_topology.Store(res_id, storeKindData); yield break; } } Destination gateway = new Destination(new NodeId(viaGateWay.Data)); Destination storeDestination = new Destination(res_id); StoreReq storeRequest = new StoreReq(storeDestination.destination_data.ressource_id, kind_data, m_machine.UsageManager, false); reloadSendMsg = create_reload_message(gateway, ++m_ReloadConfig.TransactionID, storeRequest); reloadSendMsg.forwarding_header.destination_list.Add(storeDestination); //this is the real destination if (reloadSendMsg.AddDestinationOverlay(ResourceName)) m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "AddDestinationOverlay successful"); } else { res_id = new ResourceId(ResourceName); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_USAGE, String.Format("Store {0} as ResID: {1}", ResourceName, res_id)); node = m_topology.routing_table.FindNextHopTo(new NodeId(res_id), true, false); if (m_ReloadConfig.IamClient && node == null) { node = m_ReloadConfig.AdmittingPeer; } if (node == null || node.Id == m_ReloadConfig.LocalNodeID) { foreach (StoreKindData storeKindData in kind_data) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TOPO, String.Format("Local storage at NodeId {0}", node.Id)); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_MEASURE, "Store:0,011111"); m_topology.Store(res_id, storeKindData); } if (storeDone != null) storeDone.Post(reloadDialog); yield break; } reloadSendMsg = create_store_req(new Destination(res_id), kind_data, false); } int RetransmissionTime = ReloadGlobals.RetransmissionTime + ReloadGlobals.MaxTimeToSendPacket; int iRetrans = ReloadGlobals.MaxRetransmissions; while (iRetrans >= 0 && m_ReloadConfig.State < ReloadConfig.RELOAD_State.Exit) { try { reloadDialog = new ReloadDialog(m_ReloadConfig, m_flm, node); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("{0} ==> {1} TransId={2:x16}", reloadSendMsg.reload_message_body.RELOAD_MsgCode.ToString().PadRight(16, ' '), node.Id, reloadSendMsg.TransactionID)); Arbiter.Activate(m_DispatcherQueue, new IterativeTask<ReloadMessage, ReloadMessageFilter, int>(reloadSendMsg, new ReloadMessageFilter(reloadSendMsg.TransactionID), RetransmissionTime, reloadDialog.Execute)); } catch (Exception ex) { storeDone.Post(reloadDialog); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "Send Store: " + ex.Message); ReloadGlobals.PrintException(m_ReloadConfig, ex); } yield return Arbiter.Receive(false, reloadDialog.Done, done => { }); if (!reloadDialog.Error && reloadDialog.ReceivedMessage != null) break; /* If a response has not been received when the timer fires, the request is retransmitted with the same transaction identifier. */ --iRetrans; } try { if (!reloadDialog.Error && reloadDialog.ReceivedMessage != null) { //the SourceNodeID delivered from reloadDialog comes from connection table and is the last hop of the message ReloadMessage reloadRcvMsg = reloadDialog.ReceivedMessage; if (reloadRcvMsg.reload_message_body.RELOAD_MsgCode == RELOAD_MessageCode.Store_Answer) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_USAGE, String.Format("Store successful:{0} <== {1} TransId={2:x16}", reloadRcvMsg.reload_message_body.RELOAD_MsgCode.ToString().PadRight(16, ' '), reloadRcvMsg.OriginatorID, reloadRcvMsg.TransactionID)); m_ReloadConfig.EndStore = DateTime.Now; TimeSpan storeSpan = storeSpan = m_ReloadConfig.EndStore - m_ReloadConfig.StartStore; if (m_ReloadConfig.IamClient) storeSpan = DateTime2.Now - m_ReloadConfig.StartStoreMobile; m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_MEASURE, String.Format("Store:{0}", storeSpan.TotalSeconds.ToString())); if (storeDone != null) storeDone.Post(reloadDialog); } } else { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_WARNING, String.Format("Store failed")); m_statistics.IncTransmissionError(); } } catch (Exception ex) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "Send Store 2: " + ex.Message); ReloadGlobals.PrintException(m_ReloadConfig, ex); } if (m_ReloadConfig.State == ReloadConfig.RELOAD_State.Shutdown) m_machine.Finish(); }
/// <summary> /// Proprietary: Starts an AppAttachProcedure which is routed through the viaGateWay Node into the "overlayName" Overlay /// </summary> /// <param name="dest">Destination to appattach to </param> /// <param name="viaGateWay">Node Id of the GateWay into interconnection Overlay</param> /// <param name="overlayName">Name of the Overlay the other Peer is participating. Needed by the Gateway for further routing.</param> /// <returns></returns> public IEnumerator<ITask> AppAttachProcedure(Destination dest, NodeId viaGateWay, string overlayName) { ReloadMessage reloadSendMsg; m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("AppAttachProcedure to {0} via GateWay {1}", dest, viaGateWay)); reloadSendMsg = create_app_attach_req(new Destination(new NodeId(viaGateWay.Data))); reloadSendMsg.forwarding_header.destination_list.Add(dest); if (reloadSendMsg.AddDestinationOverlay(overlayName)) m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "AddDestinationOverlay successful"); //create_reload_message(new ReloadMessage(m_ReloadConfig, m_topology.LocalNode.Id, dest, ++m_ReloadConfig.TransactionID, new AppAttachReqAns(m_topology.LocalNode, true))); if (dest.type != DestinationType.node) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("AppAttachProcedure failed: unexpected destination type")); yield break; } if (dest.destination_data.node_id == m_topology.Id) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("local AppAttachProcedure dropped")); yield break; } //Node node = m_topology.routing_table.FindNextHopTo(dest.destination_data.node_id, true, false); Node node = m_topology.routing_table.FindNextHopTo(viaGateWay, true, false); if (node == null) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("AppAttachProcedure: failed, did not found next hop to {0}", dest.destination_data.node_id)); yield break; } ReloadDialog reloadDialog = null; int RetransmissionTime = ReloadGlobals.RetransmissionTime + ReloadGlobals.MaxTimeToSendPacket; int iRetrans = ReloadGlobals.MaxRetransmissions; m_topology.routing_table.SetNodeState(dest.destination_data.node_id, NodeState.attaching); while (iRetrans >= 0 && m_ReloadConfig.State < ReloadConfig.RELOAD_State.Shutdown) { try { /* use a new ReloadDialog instance for every usage, Monitor requires it */ reloadDialog = new ReloadDialog(m_ReloadConfig, m_flm, node); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("{0} via {1} ==> Dest={2} TransId={3:x16}", RELOAD_MessageCode.App_Attach_Request.ToString().PadRight(16, ' '), node, dest.ToString(), reloadSendMsg.TransactionID)); Arbiter.Activate(m_DispatcherQueue, new IterativeTask<ReloadMessage, ReloadMessageFilter, int>(reloadSendMsg, new ReloadMessageFilter(reloadSendMsg.TransactionID), RetransmissionTime, reloadDialog.Execute)); } catch (Exception ex) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "AppAttachProcedure: " + ex.Message); } yield return Arbiter.Receive(false, reloadDialog.Done, done => { }); if (!reloadDialog.Error && reloadDialog.ReceivedMessage != null) break; /* If a response has not been received when the timer fires, the request is retransmitted with the same transaction identifier. */ --iRetrans; } try { if (!reloadDialog.Error && reloadDialog.ReceivedMessage != null) { //the SourceNodeID delivered from reloadDialog comes from connection table and is the last hop of the message ReloadMessage reloadRcvMsg = reloadDialog.ReceivedMessage; if (reloadRcvMsg.reload_message_body.RELOAD_MsgCode == RELOAD_MessageCode.App_Attach_Answer) { AppAttachReqAns answ = (AppAttachReqAns)reloadRcvMsg.reload_message_body; if (answ != null) { node = new Node(reloadRcvMsg.OriginatorID, answ.ice_candidates); /* An Attach in and of itself does not result in updating the routing * table of either node. * Note: We use the routing table here only for storing ice candidates * for later use, we will not update successor or predecessor list */ m_topology.routing_table.AddNode(node); if (m_topology.routing_table.GetNodeState(node.Id) < NodeState.attached) m_topology.routing_table.SetNodeState(node.Id, NodeState.attached); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("{0} <== {1} last={2} TransId={3:x16}", reloadRcvMsg.reload_message_body.RELOAD_MsgCode.ToString().PadRight(16, ' '), reloadRcvMsg.OriginatorID, reloadRcvMsg.LastHopNodeId, reloadRcvMsg.TransactionID)); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_USAGE, String.Format("AppAttach returns IP: {0}", answ.ice_candidates[0].addr_port.ipaddr.ToString())); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_USAGE, String.Format("AppAttach returns IP: {0}:{1}", answ.ice_candidates[0].addr_port.ipaddr.ToString(), answ.ice_candidates[0].addr_port.port.ToString())); /* Proprietary registry interface function to support external clients */ ReloadGlobals.StoreRegAnswer("sip:" + answ.ice_candidates[0].addr_port.ipaddr.ToString() + ":5060"); m_ReloadConfig.ConnEstEnd = DateTime.Now; } } } else { m_topology.routing_table.SetNodeState(dest.destination_data.node_id, NodeState.unknown); } } catch (Exception ex) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "AppAttachProcedure: " + ex.Message); m_topology.routing_table.SetNodeState(dest.destination_data.node_id, NodeState.unknown); } }
public bool GotUpdatesFrom(NodeId nodeid) { NodeState nodestate = GetNodeState(nodeid); return nodestate == NodeState.updates_received; }
public char GetStatusShortLetter(NodeId nodeid) { NodeState nodestate = GetNodeState(nodeid); switch (nodestate) { case NodeState.updates_received: return 'U'; case NodeState.attached: return 'A'; case NodeState.attaching: return 'I'; case NodeState.unknown: return '?'; } return ' '; }
public bool IsWaitForJoinAnsw(NodeId nodeid) { RTableEntry rtable; if (nodeid != null && m_RtTable.TryGetValue(nodeid.ToString(), out rtable)) { return rtable.wait_for_join_answ; } return false; }
public bool IsAttached(NodeId nodeid) { NodeState nodestate = GetNodeState(nodeid); return nodestate == NodeState.attached || nodestate == NodeState.updates_received; }
public bool GetPing(NodeId nodeid) { RTableEntry rtable; if (nodeid != null && m_RtTable.TryGetValue(nodeid.ToString(), out rtable)) { return rtable.pinging; } return false; }
/// <summary> /// We need the information if a node (nodeid) has already been attached to /// and is valid. This is stored in the routing table /// </summary> /// <param name="nodeid">The Node Id</param> /// <returns>bool</returns> public NodeState GetNodeState(NodeId nodeid) { RTableEntry rtable; if (nodeid != null && m_RtTable.TryGetValue(nodeid.ToString(), out rtable)) { return rtable.nodestate; } return NodeState.unknown; }
/// <summary> /// Returns the ice candidates stored in a dicationary along with a nodeid /// </summary> /// <param name="nodeid">The Node Id</param> /// <returns>List<IceCandidate></returns> /// <summary> public List<IceCandidate> GetCandidates(NodeId nodeid) { RTableEntry rtable; if (nodeid != null && m_RtTable.TryGetValue(nodeid.ToString(), out rtable)) return rtable.icecandidates; return null; }
public void SetFingerState(NodeId finger, NodeState state) { foreach (FTableEntry fte in m_FingerTable) if (fte.Successor == finger) fte.nodestate = state; }
public Node GetNode(NodeId node_id) { RTableEntry rte; if (node_id == null) return null; m_RtTable.TryGetValue(node_id.ToString(), out rte); if (rte != null) return rte.node; else return new Node(node_id, GetCandidates(node_id)); }
/// <summary> /// If any peer sends an update we merge this information with our local tables /// </summary> /// <param name="Originator">The originator of the update message</param> /// <param name="successors">List of successors provided</param> /// <param name="predecessors">List of predecessors provided</param> /// <param name="transport">The transport layer.</param> /// <param name="transport">The forwarding layer.</param> /// <returns>IEnumerator<ITask></returns> internal IEnumerator<ITask> Merge(NodeId originator, UpdateReqAns req_answ, Boolean ForceSendUpdate) { /* When a peer, N, receives an Update request, it examines the Node-IDs in the UpdateReq and at its neighbor table and decides if this * UpdateReq would change its neighbor table.*/ lock ("merge") { try { if (!IsAttached(originator)) m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_WARNING, String.Format("A none attached node sent me an update {0}:", originator)); List<NodeId> total_update_list = new List<NodeId>(); var validSuccessors = new List<NodeId>(); var validPredecessors = new List<NodeId>(); if (LeavingNodes.Count > 0) { if (!LeavingNodes.ContainsKey(originator)) total_update_list.Add(originator); List<NodeId> keys = LeavingNodes.Keys.ToList(); foreach (NodeId node in req_answ.Successors) { if (!keys.Contains(node)) validSuccessors.Add(node); } total_update_list.AddRange(validSuccessors); foreach (NodeId node in req_answ.Predecessors) { if (!keys.Contains(node)) validPredecessors.Add(node); } total_update_list.AddRange(validPredecessors); } else { total_update_list.Add(originator); total_update_list.AddRange(req_answ.Successors); total_update_list.AddRange(req_answ.Predecessors); } m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("<== Successors from {0}:", originator)); for (int i = req_answ.Successors.Count - 1; i >= 0; i--) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format(" S{0}: {1}", i, req_answ.Successors[i])); } m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("<== Predecessors from {0}:", originator)); for (int i = 0; i < req_answ.Predecessors.Count; i++) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format(" P{0}: {1}", i, req_answ.Predecessors[i])); } total_update_list = removeDuplicates(total_update_list); if (m_ReloadConfig.IamClient) { if (m_ReloadConfig.AdmittingPeer != null) { NodeId nodeid = m_ReloadConfig.AdmittingPeer.Id; foreach (NodeId id in total_update_list) { if (id.ElementOfInterval(m_local_node.Id, nodeid, false)) nodeid = id; } //found a new admitting (responsible) peer if (nodeid != m_local_node.Id && nodeid != m_ReloadConfig.AdmittingPeer.Id) { NodeState nodestate = GetNodeState(nodeid); if (nodestate == NodeState.unknown) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TOPO, String.Format("Found a new admitting peer: {0} via {1}", nodeid, originator)); Arbiter.Activate(m_DispatcherQueue, new IterativeTask<Destination, NodeId, AttachOption>( new Destination(nodeid), originator, AttachOption.forceupdate, m_transport.AttachProcedure)); } } } yield break; } foreach (NodeId id in total_update_list) { if (id != originator) { NodeId value; if (m_LearnedFromTable.TryGetValue(id.ToString(), out value)) { if (IsAttached(originator) && value != originator) { m_LearnedFromTable.Remove(id.ToString()); m_LearnedFromTable.Add(id.ToString(), originator); //m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format(" Upd: Learned {0} from {1}", id, originator)); } } else { m_LearnedFromTable.Add(id.ToString(), originator); //m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format(" New: Learned {0} from {1}", id, originator)); } } } total_update_list.AddRange(m_successors); total_update_list.AddRange(m_predecessors); total_update_list = removeDuplicates(total_update_list); List<NodeId> m_new_predecessors = NeighborsFromTotal(total_update_list, false); List<NodeId> m_new_successors = NeighborsFromTotal(total_update_list, true); // REPLICATEST foreach (NodeId node in LeavingNodes.Keys) { if (m_new_predecessors.Contains(node)) m_new_predecessors.Remove(node); if (m_new_successors.Contains(node)) m_new_successors.Remove(node); } Boolean fAnyNewNeighbor = false; /* if( IsChangedList(GetApproved(m_predecessors), GetApproved(m_new_predecessors)) || IsChangedList(GetApproved(m_successors), GetApproved(m_new_successors))) { fNewUpdateRequired = true; } */ if (IsChangedList(m_predecessors, m_new_predecessors) || IsChangedList(m_successors, m_new_successors)) { fAnyNewNeighbor = true; } if (IsChangedList(m_predecessors, m_new_predecessors)) { //got new predecessor. Handover Keys Arbiter.Activate(m_ReloadConfig.DispatcherQueue, new IterativeTask<bool>(false, m_transport.HandoverKeys)); } if (IsChangedList(m_successors, m_new_successors)) { List<NodeId> nodesWithReplicas = new List<NodeId>(); if(m_successors.Count > 0) nodesWithReplicas.Add(m_successors[0]); if (m_successors.Count > 1) nodesWithReplicas.Add(m_successors[1]); if(m_new_successors.Count > 0) if(!nodesWithReplicas.Contains(m_new_successors[0])) Arbiter.Activate(m_ReloadConfig.DispatcherQueue, new IterativeTask<NodeId>(m_new_successors[0], m_transport.StoreReplicas)); if (m_new_successors.Count > 1) if(!nodesWithReplicas.Contains(m_new_successors[1])) Arbiter.Activate(m_ReloadConfig.DispatcherQueue, new IterativeTask<NodeId>(m_new_successors[1], m_transport.StoreReplicas)); } m_predecessors = m_new_predecessors; m_successors = m_new_successors; // update all neighbors on changes in the local neighbor table if (fAnyNewNeighbor || ForceSendUpdate) { PrintNeigborState(); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_BUG, String.Format("Merge: New approved neighbors, send updates to all")); SendUpdateToAllNeighbors(); } } catch (Exception ex) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "Merge: " + ex.Message); ReloadGlobals.PrintException(m_ReloadConfig, ex); //System.Diagnostics.Debugger.Break(); } } // 6. AP MUST do a series of Store requests to JP to store the data // that will be responsible for. RELOAD base -13 p.105 // m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, "Handover Keys"); // Arbiter.Activate(m_DispatcherQueue, new IterativeTask<Boolean>(false, m_transport.HandoverKeys)); yield break; }
public Node FindNextHopTo(NodeId TargetId, bool fIncluding, bool fExludeMe) { /* Nodes of the connection table may be not part of the ring. So never * use them as via nodes */ foreach (ReloadConnectionTableInfoElement rce in m_flm.ConnectionTable) if (rce.NodeID != null && rce.NodeID == TargetId) return GetNode(rce.NodeID); /* Already in routing table? Route to destination directly then */ if (GotUpdatesFrom(TargetId)) return GetNode(TargetId); /* As Client always contact admitting peer and do not forward anything * as long as not having joined (bootstraps are an exception) */ if (m_ReloadConfig.IamClient) return m_ReloadConfig.AdmittingPeer; /* Now use any information available to find the hop nearest to * destination where we have ice candidates of or have an existing * connection to */ if (m_successors.Count == 0) return m_local_node; if (TargetId.ElementOfInterval(GetPredecessor(0).Id, m_local_node.Id, true)) return m_local_node; foreach (NodeId succ in m_successors) { if (TargetId.ElementOfInterval(m_local_node.Id, succ, false) || TargetId == succ) return GetNode(succ); } Node closestNode = GetClosestPrecedingNode(TargetId); return closestNode; //return FindNextHopTo(closestNode.Id, false , false); // watch out! NextHopId might be null //return GetNode(NextHopId); }
/// <summary> /// Proprietary: Tries to fetch the Data specified by the StoredDataSpecifier List from different RELOAD overlay using viaGateWay as gateway /// </summary> /// <param name="resourceName"></param> /// <param name="specifiers"></param> /// <param name="viaGateWay"></param> /// <returns></returns> public IEnumerator<ITask> Fetch(string resourceName, List<StoredDataSpecifier> specifiers, NodeId viaGateWay) { ReloadDialog reloadDialog = null; ReloadMessage reloadSendMsg; List<IUsage> recUsages = new List<IUsage>(); ResourceId res_id = new ResourceId(resourceName); Node node = null; List<FetchKindResponse> fetchKindResponses = new List<FetchKindResponse>(); FetchKindResponse fetchKindResponse = null; if (viaGateWay != null) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_USAGE, String.Format("Fetch {0} as ResID: {1} via Gateway {2}", resourceName, res_id, viaGateWay)); node = m_topology.routing_table.FindNextHopTo(viaGateWay, true, false); //node = m_topology.routing_table.FindNextHopTo(new NodeId(res_id), true, false); if (m_ReloadConfig.IamClient && node == null) { node = m_ReloadConfig.AdmittingPeer; } Destination gateway = new Destination(new NodeId(viaGateWay.Data)); Destination fetchDestination = new Destination(res_id); //reloadSendMsg = create_fetch_req(gateway, specifiers); FetchReq fetchRequest = new FetchReq(fetchDestination.destination_data.ressource_id, specifiers, m_machine.UsageManager); reloadSendMsg = create_reload_message(gateway, ++m_ReloadConfig.TransactionID, fetchRequest); reloadSendMsg.forwarding_header.destination_list.Add(fetchDestination); //reloadSendMsg = create_fetch_req(new Destination(res_id), specifiers); //reloadSendMsg.AddViaHeader(viaGateWay); if (reloadSendMsg.AddDestinationOverlay(resourceName)) m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "AddDestinationOverlay successful"); } else { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_USAGE, String.Format("Fetch {0} as ResID: {1}", resourceName, res_id)); node = m_topology.routing_table.FindNextHopTo(new NodeId(res_id), true, false); if (m_ReloadConfig.IamClient && node == null) { node = m_ReloadConfig.AdmittingPeer; } List<Destination> dest_list = new List<Destination>(); dest_list.Add(new Destination(m_topology.LocalNode.Id)); if (node == null || node.Id == m_ReloadConfig.LocalNodeID) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TOPO, "Local Fetch."); m_ReloadConfig.StartFetchAttach = DateTime.Now; foreach (StoredDataSpecifier specifier in specifiers) { var responses = new List<FetchKindResponse>(); if (m_topology.Fetch(res_id, specifier, out fetchKindResponse)) { responses.Add(fetchKindResponse); foreach (StoredData sd in fetchKindResponse.values) { if (m_ReloadConfig.AccessController.validateDataSignature(res_id, fetchKindResponse.kind, sd)) recUsages.Add(sd.Value.GetUsageValue); else { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TOPO, "DATA SIGNATURE INVALID!!"); } m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TOPO, String.Format("Fetch successful, got {0}", sd.Value.GetUsageValue.Report())); } m_ReloadConfig.ConnEstEnd = DateTime.Now; } OnFetchedData(res_id, responses); } if (fetchDone != null) { if (recUsages.Count == 0) { foreach (StoredDataSpecifier specifier in specifiers) recUsages.Add(new NoResultUsage(specifier.ResourceName)); } fetchDone.Post(recUsages); } yield break; } else { reloadSendMsg = create_fetch_req(new Destination(res_id), specifiers); } } int RetransmissionTime = ReloadGlobals.RetransmissionTime + ReloadGlobals.MaxTimeToSendPacket; int iRetrans = ReloadGlobals.MaxRetransmissions; while (iRetrans >= 0 && m_ReloadConfig.State < ReloadConfig.RELOAD_State.Shutdown) { try { reloadDialog = new ReloadDialog(m_ReloadConfig, m_flm, node); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("{0} ==> {1} TransId={2:x16}", reloadSendMsg.reload_message_body.RELOAD_MsgCode.ToString(). PadRight(16, ' '), node.Id, reloadSendMsg.TransactionID)); m_ReloadConfig.StartFetchAttach = DateTime.Now; Arbiter.Activate(m_DispatcherQueue, new IterativeTask<ReloadMessage, ReloadMessageFilter, int>( reloadSendMsg, new ReloadMessageFilter(reloadSendMsg.TransactionID), RetransmissionTime, reloadDialog.Execute)); } catch (Exception ex) { fetchDone.Post(new List<IUsage> { new NullUsage() }); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "Fetch: " + ex.Message); } yield return Arbiter.Receive(false, reloadDialog.Done, done => { }); if (!reloadDialog.Error && reloadDialog.ReceivedMessage != null) break; /* If a response has not been received when the timer fires, the request is retransmitted with the same transaction identifier. */ --iRetrans; } try { if (!reloadDialog.Error && reloadDialog.ReceivedMessage != null) { //the SourceNodeID delivered from reloadDialog comes from connection table and is the last hop of the message ReloadMessage reloadRcvMsg = reloadDialog.ReceivedMessage; RELOAD_MessageCode recMsgCode = reloadRcvMsg.reload_message_body.RELOAD_MsgCode; if (recMsgCode == RELOAD_MessageCode.Fetch_Answer) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("{0} <== {1} TransId={2:x16}", recMsgCode.ToString().PadRight(16, ' '), reloadRcvMsg.OriginatorID, reloadRcvMsg.TransactionID)); FetchAns answ = (FetchAns)reloadRcvMsg.reload_message_body; if (answ != null) { fetchKindResponses = answ.KindResponses; foreach (FetchKindResponse kind in fetchKindResponses) { foreach (StoredData sd in kind.values) { if (m_ReloadConfig.AccessController.validateDataSignature(res_id, kind.kind, sd)) recUsages.Add(sd.Value.GetUsageValue); else { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TOPO, "DATA SIGNATURE INVALID!!"); } m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TOPO, String.Format("Fetch successful, got {0}", sd.Value.GetUsageValue.Report())); } } OnFetchedData(res_id, fetchKindResponses); if (fetchDone != null) { if (recUsages.Count == 0) { foreach (StoredDataSpecifier specifier in specifiers) recUsages.Add(new NoResultUsage(specifier.ResourceName)); } fetchDone.Post(recUsages); } } } } else { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_WARNING, String.Format("Fetch failed")); foreach (StoredDataSpecifier specifier in specifiers) recUsages.Add(new NoResultUsage(specifier.ResourceName)); fetchDone.Post(recUsages); m_statistics.IncTransmissionError(); } } catch (Exception ex) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "Fetch: " + ex.Message); } }
private Node GetClosestPrecedingNode(NodeId key) { /* List of all remote peers*/ List<NodeId> mexthop_list = new List<NodeId>(); /* insert all successors into list */ mexthop_list.AddRange(m_successors); /* predecessor is appropriate only if it precedes the given id */ if (m_predecessors.Count > 0) foreach (NodeId pre in m_predecessors) if (key.ElementOfInterval(pre, m_local_node.Id, false)) mexthop_list.AddRange(m_predecessors); /* determine closest preceding reference of finger table */ Node closetPrecedingFinger = GetClosestPrecedingFinger(key); if (closetPrecedingFinger != null) mexthop_list.Add(closetPrecedingFinger.Id); Node closestNode = null; mexthop_list.Add(key); mexthop_list = removeDuplicates(mexthop_list); int sizeOfList = mexthop_list.Count; if (sizeOfList > 1) mexthop_list.Sort(); /* * The list item with one index lower than that of the key must be the * id of the closest predecessor or the key. */ int keyIndex = mexthop_list.IndexOf(key); /* * As all ids are located on a ring if the key is the first item in the * list we have to select the last item as predecessor with help of this * calculation. */ int index = (sizeOfList + (keyIndex - 1)) % sizeOfList; NodeId idOfClosestNode = mexthop_list[index]; closestNode = GetNode(idOfClosestNode); return closestNode; }
/// <summary> /// Store Replicas: My next two successors have changed. Replicate my data /// </summary> /// <param name="node"></param> /// <returns></returns> public IEnumerator<ITask> StoreReplicas(NodeId node) { // For each Resource stored at this Peer, handover StoredData List<string> storedKeys; if ((storedKeys = m_topology.Storage.StoredKeys) != null && storedKeys.Count > 0) { m_topology.Storage.RemoveExpired(); Dictionary<ResourceId, List<StoreKindData>> nodes = new Dictionary<ResourceId, List<StoreKindData>>(); foreach (string key in storedKeys) { ResourceId res_id = new ResourceId(ReloadGlobals.HexToBytes(key)); if (!m_topology.Replicas.Contains(key)) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TOPO, "Store Replicas - will send store requests"); if (!nodes.ContainsKey(res_id)) { nodes.Add(res_id, new List<StoreKindData>()); nodes[res_id].AddRange(m_topology.Storage.GetStoreKindData(key)); } else { nodes[res_id].AddRange(m_topology.Storage.GetStoreKindData(key)); } } } ReloadDialog reloadDialog = null; ReloadMessage reloadSendMsg; List<StoreKindData> storeKindData; foreach (ResourceId res_id in nodes.Keys) { storeKindData = nodes[res_id]; m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TOPO, "GOING TO REPLICATE UNDER RES_ID: " + res_id + " AT NODE: " + node); List<SignerIdentity> signers = new List<SignerIdentity>(); foreach (StoreKindData skd in storeKindData) { foreach (StoredData sd in skd.Values) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TOPO, "STOREDATA: " + sd.Value.GetUsageValue.Report()); // add certificate if (!signers.Contains(sd.Signature.Identity)) signers.Add(sd.Signature.Identity); } } reloadSendMsg = create_store_req(new Destination(node), res_id, storeKindData, true); // get certificates for this data List<GenericCertificate> certs = new List<GenericCertificate>(); certs.AddRange(m_ReloadConfig.AccessController.GetPKCs(signers)); // add certificates to fetch answer reloadSendMsg.security_block.Certificates.AddRange(certs); int RetransmissionTime = ReloadGlobals.RetransmissionTime + ReloadGlobals.MaxTimeToSendPacket; int iRetrans = ReloadGlobals.MaxRetransmissions; while (iRetrans >= 0 && m_ReloadConfig.State < ReloadConfig.RELOAD_State.Exit) { try { reloadDialog = new ReloadDialog(m_ReloadConfig, m_flm, m_topology.routing_table.FindNextHopTo(node, false, false)); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("{0} ==> {1} TransId={2:x16}", reloadSendMsg.reload_message_body.RELOAD_MsgCode.ToString().PadRight(16, ' '), node, reloadSendMsg.TransactionID)); Arbiter.Activate(m_DispatcherQueue, new IterativeTask<ReloadMessage, ReloadMessageFilter, int>(reloadSendMsg, new ReloadMessageFilter(reloadSendMsg.TransactionID), RetransmissionTime, reloadDialog.Execute)); } catch (Exception ex) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "Send Store: " + ex.Message); } yield return Arbiter.Receive(false, reloadDialog.Done, done => { }); if (!reloadDialog.Error && reloadDialog.ReceivedMessage != null) break; /* If a response has not been received when the timer fires, the request is retransmitted with the same transaction identifier. */ --iRetrans; } try { if (!reloadDialog.Error && reloadDialog.ReceivedMessage != null) { ReloadMessage reloadRcvMsg = reloadDialog.ReceivedMessage; if (reloadRcvMsg.reload_message_body.RELOAD_MsgCode == RELOAD_MessageCode.Store_Answer) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("{0} <== {1} TransId={2:x16}", reloadRcvMsg.reload_message_body.RELOAD_MsgCode.ToString().PadRight(16, ' '), reloadRcvMsg.OriginatorID, reloadRcvMsg.TransactionID)); //StoreReqAns answ = (StoreReqAns)reloadRcvMsg.reload_message_body; --old StoreAns answ = (StoreAns)reloadRcvMsg.reload_message_body; // --alex if (answ != null) { } } } else { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_WARNING, String.Format("Store Replica failed")); m_statistics.IncTransmissionError(); } } catch (Exception ex) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "Send Store Replica: " + ex.Message); } } } }
private Node GetClosestPrecedingFinger(NodeId key) { List<NodeId> successorIds = new List<NodeId>(); List<FTableEntry> successors = new List<FTableEntry>(); foreach (FTableEntry ft in FingerTable) if (!successorIds.Contains(ft.Successor) && ft.nodestate == NodeState.updates_received) { successorIds.Add(ft.Successor); successors.Add(ft); } foreach (FTableEntry finger in successors) { if (finger.Successor != null && finger.Successor.ElementOfInterval(m_local_node.Id, key, false)// && )//GotUpdatesFrom(finger.Successor)) return GetNode(finger.Successor); } return null; }
public void InboundClose(NodeId nodeid) { Boolean important_node = m_topology.routing_table.NodeWeNeed(nodeid); if (important_node) Arbiter.Activate(m_DispatcherQueue, new IterativeTask<Destination, PingOption>(new Destination(nodeid), PingOption.direct, SendPing)); }
internal void SetNodeState(NodeId nodeId, NodeState nodestate) { try { RTableEntry rtable; lock (m_RtTable) { if (nodeId != null && m_RtTable.TryGetValue(nodeId.ToString(), out rtable)) { NodeState oldstate = rtable.nodestate; switch (rtable.nodestate) { case NodeState.unknown: rtable.nodestate = nodestate; break; case NodeState.attaching: rtable.nodestate = nodestate; break; case NodeState.attached: if (nodestate == NodeState.attaching) { //m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "SetNodeState: invalid transition from attached to attaching"); //ignore, should only occur on AppAttach } else { if (nodestate == NodeState.attached & m_UpdateReceivedFromUnattachedNode.Contains(nodeId)) { m_UpdateReceivedFromUnattachedNode.Remove(nodeId); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, "SetNodeState: attached -> updates_received on saved state"); rtable.nodestate = NodeState.updates_received; } else rtable.nodestate = nodestate; } break; case NodeState.updates_received: //ignore attach messages here if (nodestate != NodeState.attached && nodestate != NodeState.attaching) rtable.nodestate = nodestate; break; } if (m_ReloadConfig.State == ReloadConfig.RELOAD_State.Joined && (nodestate == NodeState.attached || rtable.nodestate == NodeState.updates_received) && (oldstate == NodeState.attaching || oldstate == NodeState.unknown)) { if (m_predecessors.Contains(nodeId) || m_successors.Contains(nodeId)) { /* A not approved node stored in successor and predecessor list became valid (attached). * This is a trigger to send an update to all (valid) neighbors */ m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_BUG, String.Format("AddNode: New approved neighbor, send updates to all")); SendUpdateToAllNeighbors(); } } } else { if (nodestate == NodeState.updates_received) { /* bad situation, we received an update but probably no attach answ so far * save this info for later use */ m_UpdateReceivedFromUnattachedNode.Add(nodeId); } } } } catch (Exception ex) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "SetNodeState: " + ex.Message); } }
/// <summary> /// Checks if a inbound message must be forwarded /// /// Returns true, if it will be forwarded /// </summary> /// <param name="reloadMsg">The inbound msg</param> /// <returns>true, if the message will be forwarded</returns> public bool ProcessMsg(ReloadMessage reloadMsg) { if (reloadMsg.OriginatorID == m_topology.LocalNode.Id) { if (m_loopedTransactions != null) m_loopedTransactions.Post(reloadMsg.TransactionID); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("Looped back and dropped {0} <== {1} TransId={2:x16}", reloadMsg.reload_message_body.RELOAD_MsgCode.ToString().PadRight(16, ' '), reloadMsg.OriginatorID, reloadMsg.TransactionID)); lock ("print via") { if (reloadMsg.forwarding_header.via_list != null) foreach (Destination via in reloadMsg.forwarding_header.via_list) m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("Via: {0}", via)); } return true; } //check for validity if (reloadMsg.forwarding_header.destination_list == null || reloadMsg.forwarding_header.destination_list.Count == 0) { //empty destination list, reply with error m_transport.send(m_transport.create_erro_reply( new Destination(m_topology.LocalNode.Id), RELOAD_ErrorCode.Error_Unsupported_Forwarding_Option, "Empty destination list", ++m_ReloadConfig.TransactionID), m_topology.routing_table.GetNode(reloadMsg.LastHopNodeId)); return true; } NextDestination: //check first entry on destination list Destination dest = reloadMsg.forwarding_header.destination_list[0]; if (reloadMsg.forwarding_header.via_list != null) { // check for a remarkable lenght of via headers, they should not exceed a special value (MAX_VIA_LIST_ENTRIES) if (reloadMsg.forwarding_header.via_list.Count > ReloadGlobals.MAX_VIA_LIST_ENTRIES) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("==> maximum via list length exceeded {0}: {1} from {2} Dest={3} TransID={4:x16}", ReloadGlobals.MAX_VIA_LIST_ENTRIES, reloadMsg.reload_message_body.RELOAD_MsgCode.ToString().PadRight(16, ' '), reloadMsg.OriginatorID, dest.ToString(), reloadMsg.TransactionID)); if (reloadMsg.forwarding_header.via_list != null) { foreach (Destination destx in reloadMsg.forwarding_header.via_list) m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("Via={0} ", destx.ToString())); } if (reloadMsg.forwarding_header.destination_list != null) { foreach (Destination desty in reloadMsg.forwarding_header.destination_list) if (desty.type != DestinationType.node || reloadMsg.forwarding_header.destination_list.Count > 1) m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format(" Dest={0} ", desty.ToString())); } return true; } } switch (dest.type) { case DestinationType.node: NodeId DestinationId = dest.destination_data.node_id; /* some loop checks first */ if (m_topology.LocalNode.Id == reloadMsg.OriginatorID) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_WARNING, String.Format("==> Suspicious: packet looped back to me: {0} from {1} Dest={2} TransID={3:x16}", reloadMsg.reload_message_body.RELOAD_MsgCode.ToString().PadRight(16, ' '), reloadMsg.OriginatorID, dest.ToString(), reloadMsg.TransactionID)); } if (DestinationId == reloadMsg.OriginatorID) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("Loop Warning: Node {0} tries to attach to itself, last hop={1} dropping request TransID={2:x16}", reloadMsg.OriginatorID, reloadMsg.LastHopNodeId, reloadMsg.TransactionID)); if (reloadMsg.forwarding_header.via_list != null) { foreach (Destination destx in reloadMsg.forwarding_header.via_list) m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format(" Via={0} ", destx.ToString())); } if (reloadMsg.forwarding_header.destination_list != null) { foreach (Destination desty in reloadMsg.forwarding_header.destination_list) if (desty.type != DestinationType.node || reloadMsg.forwarding_header.destination_list.Count > 1) m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format(" Dest={0} ", desty.ToString())); } return true; } if (reloadMsg.forwarding_header.via_list != null) { foreach (Destination destination in reloadMsg.forwarding_header.via_list) { if (destination.type == DestinationType.node && destination.destination_data.node_id == DestinationId) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_WARNING, String.Format("==> packet looped back to me I'm already in via list: {0} from {1} Dest={2} TransID={3:x16}", reloadMsg.reload_message_body.RELOAD_MsgCode.ToString().PadRight(16, ' '), reloadMsg.OriginatorID, dest.ToString(), reloadMsg.TransactionID)); if (reloadMsg.forwarding_header.via_list != null) { foreach (Destination destx in reloadMsg.forwarding_header.via_list) m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format(" Via={0} ", destx.ToString())); } if (reloadMsg.forwarding_header.destination_list != null) { foreach (Destination desty in reloadMsg.forwarding_header.destination_list) if (desty.type != DestinationType.node || reloadMsg.forwarding_header.destination_list.Count > 1) m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format(" Dest={0} ", desty.ToString())); } } } } //is this this node? if (DestinationId == m_topology.LocalNode.Id || DestinationId == ReloadGlobals.WildcardNodeId) { //one single entry only? if (reloadMsg.forwarding_header.destination_list.Count == 1) //message for local node return false; else { //remove local node from destination list reloadMsg.RemoveFirstDestEntry(); reloadMsg.AddViaHeader(m_topology.LocalNode.Id); if (handleInterdomainMessage(reloadMsg)) return true; //message was processed! forwarded via GateWay! goto NextDestination; } } Node NextHopNode = null; foreach (ReloadConnectionTableInfoElement rce in m_flm.ConnectionTable) { if (rce.NodeID != null && rce.NodeID == DestinationId) { NextHopNode = m_topology.routing_table.GetNode(DestinationId); break; } } /* Do we have ice candidates already from destination? */ if (NextHopNode == null) if (m_topology.routing_table.IsAttached(DestinationId)) NextHopNode = m_topology.routing_table.GetNode(DestinationId); /* no direct physical parameters available? -> use routing */ if (NextHopNode == null) /* The Topology Plugin is responsible for maintaining the overlay algorithm Routing Table, which is consulted by the Forwarding and Link Management Layer before routing a message. */ NextHopNode = m_topology.routing_table.FindNextHopTo( dest.destination_data.node_id, true, false); if (NextHopNode == null || NextHopNode.Id == m_topology.LocalNode.Id) { if (reloadMsg.OriginatorID != m_topology.LocalNode.Id) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("==> failed forwarding: {0} from {1} Dest={2}" + " TransID={3:x16}", reloadMsg.reload_message_body.RELOAD_MsgCode.ToString().PadRight(16, ' '), reloadMsg.OriginatorID, dest.ToString(), reloadMsg.TransactionID)); m_transport.send(m_transport.create_erro_reply( new Destination(reloadMsg.OriginatorID), RELOAD_ErrorCode.Error_Not_Found, "Node not found", ++m_ReloadConfig.TransactionID), m_topology.routing_table.GetNode(reloadMsg.LastHopNodeId)); } } else { if (NextHopNode.Id == reloadMsg.OriginatorID) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_WARNING, String.Format("Topo claims Originator responsible:" + " {0} from {1} Dest={2} TransID={3:x16}", reloadMsg.reload_message_body.RELOAD_MsgCode.ToString().PadRight(16, ' '), reloadMsg.OriginatorID, dest.ToString(), reloadMsg.TransactionID)); } if (reloadMsg.IsRequest()) { reloadMsg.AddViaHeader(m_topology.LocalNode.Id); } //else // reloadMsg.PutViaListToDestination(); reloadMsg.LastHopNodeId = m_topology.LocalNode.Id; m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_FORWARDING, String.Format("==> forwarding: {0} from {1} ==> {2} Dest={3} TransID={4:x16}", reloadMsg.reload_message_body.RELOAD_MsgCode.ToString().PadRight(16, ' '), reloadMsg.OriginatorID, NextHopNode.ToString(), dest.ToString(), reloadMsg.TransactionID)); m_transport.send(reloadMsg, NextHopNode); } break; case DestinationType.resource: { DestinationId = new NodeId(dest.destination_data.ressource_id); NodeId test = new NodeId(HexStringConverter.ToByteArray( "464201D3D1BDA43AC047ECD75CE6201D")); if (DestinationId == test) m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_USAGE, ""); /* The Topology Plugin is responsible for maintaining the overlay algorithm Routing Table, which is consulted by the Forwarding and Link Management Layer before routing a message. */ if (DestinationId == m_topology.LocalNode.Id) // || (m_topology.routing_table.Predecessors.Count > 0 && //DestinationId.ElementOfInterval(m_topology.routing_table.Predecessors[0], m_ReloadConfig.LocalNodeID, false))) //message for local node return false; /* be carefull here, if this request looped back to us, exclude us from the possible forwarding targets */ NextHopNode = m_topology.routing_table.FindNextHopTo(DestinationId, true, m_topology.LocalNode.Id == reloadMsg.OriginatorID); if (NextHopNode == null) { //we did not found another node responsible, so we are => message for local node return false; } else if (NextHopNode.Id == m_topology.LocalNode.Id) { //silently drop packet if there is more then one entry in destination list if (reloadMsg.forwarding_header.destination_list.Count > 1) break; //message for local node return false; } else { if (reloadMsg.IsRequest()) reloadMsg.AddViaHeader(m_topology.LocalNode.Id); else reloadMsg.RemoveFirstDestEntry(); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_FORWARDING, String.Format("==> forwarding: {0} from {1} ==> {2} Dest={3} TransID={4:x16}", reloadMsg.reload_message_body.RELOAD_MsgCode.ToString().PadRight(16, ' '), reloadMsg.OriginatorID, NextHopNode.ToString(), dest.ToString(), reloadMsg.TransactionID)); /* don't use create_reload* as it puts via header to destination */ m_transport.send(reloadMsg, NextHopNode); } } break; case DestinationType.compressed: //empty destination list, reply with error m_transport.send(m_transport.create_erro_reply( new Destination(reloadMsg.OriginatorID), RELOAD_ErrorCode.Error_Unsupported_Forwarding_Option, "Compressed destination type not supported", ++m_ReloadConfig.TransactionID), m_topology.routing_table.GetNode(reloadMsg.LastHopNodeId)); break; } return true; }
/// <summary> /// Returns true, if the tested Finger is needed for fingertable /// </summary> /// <param name="testFinger"></param> /// <returns></returns> public bool isFinger(NodeId testFinger) { FTableEntry finger = null; return isFinger(testFinger, out finger); }
} // end AttachFingers /// <summary> /// Returns true if attaching Node should be added to finger table. /// </summary> /// <param name="testFinger">The attaching node</param> /// <param name="finger">The first Finger Table entry machting the attaching node.</param> /// <returns>Boolean</returns> public bool isFinger(NodeId testFinger, out FTableEntry finger) { foreach (FTableEntry ftEntry in FingerTable) { if (ftEntry.nodestate == NodeState.unknown) { if (ftEntry.Finger.ElementOfInterval(m_local_node.Id, testFinger, true)) { finger = ftEntry; return true; } } else { // is closer? if (testFinger.ElementOfInterval(ftEntry.Finger, ftEntry.Successor, false)) { finger = ftEntry; return true; } } } finger = null; return false; }
internal void SetPinging(NodeId nodeId, bool ping, bool success) { try { RTableEntry rtable_entry; lock (m_RtTable) { if (nodeId != null && m_RtTable.TryGetValue(nodeId.ToString(), out rtable_entry)) { rtable_entry.pinging = ping; if (success) rtable_entry.dtLastSuccessfullPing = DateTime.Now; } } } catch (Exception ex) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "SetPinging: " + ex.Message); } }