Ejemplo n.º 1
0
        public IEnumerator<ITask> PreJoinProdecure(List<BootstrapServer> BootstrapServerList)
        {
            bool attached = false;
            ulong bsTransId = 0;

            if (m_topology.LocalNode.Id == null)
                yield break;

            ReloadMessage reloadSendMsg;
            ReloadMessage reloadRcvMsg = null;

            /* This is the begin of populating the neighbor table
               convert local node to resource id + 1 and sent an attach to it
             */
            Destination dest = new Destination(new ResourceId(
              m_topology.LocalNode.Id + (byte)1));
            Destination last_destination = null;
            Node NextHopNode = null;
            int succSize = m_ReloadConfig.IamClient ? 1 : ReloadGlobals.SUCCESSOR_CACHE_SIZE;
            for (int i = 0; i < succSize; i++)
            {
                //if (last_destination != null && last_destination == dest)
                if (last_destination != null && last_destination.Equals(dest))    // markus: we have to use Equals method
                    break;
                if (m_ReloadConfig.IamClient)
                    reloadSendMsg = create_attach_req(dest, false);
                else
                    reloadSendMsg = create_attach_req(dest, true);

                //we do not know the bootstrap peer's node id so far so we leave that parameter empty Node(null)

                ReloadDialog reloadDialog = null;
                int RetransmissionTime = ReloadGlobals.RetransmissionTime + ReloadGlobals.MaxTimeToSendPacket;

                /* Modification for Clients out of draft, TLS stack will take some time
                 * to initialize, add another 10s waiting */
                if (m_ReloadConfig.IamClient && i == 0)
                    RetransmissionTime += 10000;

                int iRetrans = ReloadGlobals.MaxRetransmissions;

                int iCycleBootstrap = 0;

                while (iRetrans >= 0 &&
                  m_ReloadConfig.State < ReloadConfig.RELOAD_State.Shutdown)
                {
                    /* This is the first bootstrap contacting sequence if NextHopNode 
                     * is still zero, in any other case 
                     * use an attach to the node where we got the last answer from 
                     */
                    if (NextHopNode == null)
                    {
                        /* we could use a foreach loop, but CCR would multitask it, but we
                         * want serialize that here
                        */
                        if (iCycleBootstrap >= BootstrapServerList.Count())
                            iCycleBootstrap = 0;

                        BootstrapServer bss = BootstrapServerList[iCycleBootstrap++];

                        if (attached == true)
                            break;

                        //TKTODO Rejoin of bootstrap server not solved 
                        List<IceCandidate> ics = new List<IceCandidate>();
                        IceCandidate ice = new IceCandidate(new IpAddressPort(
                          AddressType.IPv4_Address, ReloadGlobals.IPAddressFromHost(
                          m_ReloadConfig, bss.Host), (UInt16)bss.Port),
                          Overlay_Link.TLS_TCP_FH_NO_ICE);

                        // markus: change cand_type to bootstrap
                        ice.cand_type = CandType.tcp_bootstrap;

                        ics.Add(ice);

                        NextHopNode = new Node(reloadRcvMsg == null ?
                          null : reloadRcvMsg.OriginatorID, ics);
                    }

                    try
                    {
                        /* use a new ReloadDialog instance for every usage, Monitor requires it                         */
                        reloadDialog = new ReloadDialog(m_ReloadConfig, m_flm, NextHopNode);

                        if (iCycleBootstrap > 0)
                        {
                            // save transaction id from request to bootstrap
                            if (NextHopNode.IceCandidates[0].addr_port.ipaddr.ToString() == BootstrapServerList[iCycleBootstrap - 1].Host &&
                                NextHopNode.IceCandidates[0].addr_port.port == BootstrapServerList[iCycleBootstrap - 1].Port)
                                bsTransId = reloadSendMsg.TransactionID;
                        }
                   
                        m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD,
                          String.Format("{0} ==> {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,
                          "PreJoinProcedure: " + ex.Message);
                    }

                    yield return Arbiter.Receive(false, reloadDialog.Done, done => { });

                    if (!reloadDialog.Error && reloadDialog.ReceivedMessage != null)
                    {
                        if (reloadDialog.ReceivedMessage.TransactionID == bsTransId)
                        {

                            if (reloadDialog.ReceivedMessage.forwarding_header.via_list.Count == 1)
                            {
                                BootstrapServer bsServer = BootstrapServerList[iCycleBootstrap - 1];
                                bsServer.NodeId = reloadDialog.ReceivedMessage.forwarding_header.via_list[0].destination_data.node_id;
                                BootstrapServerList.RemoveAt(iCycleBootstrap - 1);
                                BootstrapServerList.Insert(iCycleBootstrap - 1, bsServer);
                                m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("Bootstrap ID: {0}", reloadDialog.ReceivedMessage.forwarding_header.via_list[0].destination_data.node_id));
                                //Console.WriteLine("Bootstrap ID: {0}", reloadDialog.ReceivedMessage.forwarding_header.via_list[0].destination_data.node_id);
                            }
                            else if (reloadDialog.ReceivedMessage.forwarding_header.via_list.Count == 2)
                            {
                                BootstrapServer bsServer = BootstrapServerList[iCycleBootstrap - 1];
                                bsServer.NodeId = reloadDialog.ReceivedMessage.forwarding_header.via_list[1].destination_data.node_id;
                                BootstrapServerList.RemoveAt(iCycleBootstrap - 1);
                                BootstrapServerList.Insert(iCycleBootstrap - 1, bsServer);
                                m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("Bootstrap ID: {0}", reloadDialog.ReceivedMessage.forwarding_header.via_list[1].destination_data.node_id));
                                //Console.WriteLine("Bootstrap ID: {0}", reloadDialog.ReceivedMessage.forwarding_header.via_list[1].destination_data.node_id);
                            }

                            bsTransId = 0;
                        }

                        break;
                    }




                    /* still bootstrapping, allow cycling trough different bootstraps by
                     * resetting NextHopNode
                     */
                    if (i == 0)
                        NextHopNode = null;

                    /* 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} Attach  {1} TransId={2:x16}", iRetrans, NextHopNode, reloadSendMsg.TransactionID));
                        m_statistics.IncRetransmission();
                    }
                    else
                    {
                        m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("Failed! Attach {0} TransId={1:x16}", NextHopNode, reloadSendMsg.TransactionID));
                        m_statistics.IncTransmissionError();
                        if (ReloadGlobals.AutoExe)
                        {
                            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "PreJoin: Exit because initial Attach Faild!");
                            m_machine.SendCommand("Exit");
                        }
                    }
                }
                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
                        reloadRcvMsg = reloadDialog.ReceivedMessage;
                        RELOAD_MessageCode msgCode = reloadRcvMsg.reload_message_body.RELOAD_MsgCode;
                        if (reloadRcvMsg != null)
                        {
                            if (msgCode == RELOAD_MessageCode.Attach_Answer)
                            {
                                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));

                                AttachReqAns answ = (AttachReqAns)reloadRcvMsg.reload_message_body;

                                if (answ != null)
                                {
                                    m_ReloadConfig.State = ReloadConfig.RELOAD_State.PreJoin;
                                    m_machine.StateUpdates(ReloadConfig.RELOAD_State.PreJoin);

                                    /*  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
                                     */
                                    NextHopNode = 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(NextHopNode);
                                    m_topology.routing_table.SetNodeState(NextHopNode.Id,
                                      NodeState.attached);

                                    if (CheckAndSetAdmittingPeer(NextHopNode) &&
                                      NextHopNode.Id != reloadRcvMsg.LastHopNodeId)
                                        // Send ping to establish a physical connection
                                        Arbiter.Activate(m_DispatcherQueue,
                                          new IterativeTask<Destination, PingOption>(new Destination(
                                          NextHopNode.Id), PingOption.direct, SendPing));

                                    if (m_ReloadConfig.IamClient)
                                    {
                                        m_ReloadConfig.LastJoinedTime = DateTime2.Now;
                                        TimeSpan joiningTime = m_ReloadConfig.LastJoinedTime - m_ReloadConfig.StartJoinMobile;
                                        m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_MEASURE,
                                          "Join:" + joiningTime.TotalSeconds.ToString());
                                    }

                                    attached = true;
                                }
                            }
                            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("Prejoin: 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);
                                    }
                                }
                            }
                        }
                        else
                        {
                            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "PreJoinProcedure: reloadRcvMsg == null!!");
                        }

                        last_destination = dest;
                        dest = new Destination(new ResourceId(reloadRcvMsg.OriginatorID) + (byte)1);
                    }
                    else
                        break;
                }
                catch (Exception ex)
                {
                    m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "PreJoinProcedure: " + ex.Message);
                }
            } // End Successor Search

            // FingerTable enrichment
            if (!m_ReloadConfig.IamClient)
            {
                List<FTEntry> fingers = m_topology.routing_table.AttachFingers();
                Port<bool> attachNextPort = null;
                Boolean attachNext = true;
                /* JP SHOULD send Attach requests to initiate connections to each of
                 * the peers in the neighbor table as well as to the desired finger
                 * table entries.
                 */
                foreach (FTEntry finger in fingers)
                {
                    attachNextPort = new Port<bool>();
                    Arbiter.Activate(m_DispatcherQueue,
                      new IterativeTask<FTEntry, Port<bool>>(
                      finger, attachNextPort, AttachFinger));
                    /* Wait for finger attach */
                    yield return Arbiter.Receive(false, attachNextPort, next =>
                    {
                        attachNext = next;
                    });
                    if (!attachNext)
                        break;

                }
            }
            /* see base -18 p.106
            /* 4.  JP MUST enter all the peers it has contacted into its routing
            /*     table.
             */
            m_topology.routing_table.Conn2Route();

            /* Once JP has a reasonable set of connections it is ready to take its 
             * place in the DHT.  It does this by sending a Join to AP.
             */
            if (m_ReloadConfig.AdmittingPeer != null)
                if (!m_ReloadConfig.IamClient)
                {
                    m_ReloadConfig.State = ReloadConfig.RELOAD_State.Joining;
                    m_machine.StateUpdates(ReloadConfig.RELOAD_State.Joining);

                    m_topology.routing_table.SetWaitForJoinAnsw(
                      m_ReloadConfig.AdmittingPeer.Id, true);

                    reloadSendMsg = create_join_req(
                      new Destination(m_ReloadConfig.AdmittingPeer.Id));
                    ReloadDialog reloadDialog = null;

                    int RetransmissionTime = ReloadGlobals.RetransmissionTime + ReloadGlobals.MaxTimeToSendPacket;
                    int iRetrans = ReloadGlobals.MaxRetransmissions;

                    while (iRetrans >= 0 && m_ReloadConfig.State < ReloadConfig.RELOAD_State.Shutdown)
                    {
                        reloadDialog = new ReloadDialog(m_ReloadConfig, m_flm, m_ReloadConfig.AdmittingPeer);

                        m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("{0} ==> {1} TransId={2:x16}", RELOAD_MessageCode.Join_Request.ToString().PadRight(16, ' '), m_ReloadConfig.AdmittingPeer, reloadSendMsg.TransactionID));

                        Arbiter.Activate(m_DispatcherQueue, new IterativeTask<ReloadMessage, ReloadMessageFilter, int>(reloadSendMsg, new ReloadMessageFilter(reloadSendMsg.TransactionID), RetransmissionTime, reloadDialog.Execute));
                        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;
                        if (iRetrans >= 0)
                        {
                            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_WARNING, String.Format("Retrans {0} Join  {1} TransId={2:x16}", iRetrans, m_ReloadConfig.AdmittingPeer, reloadSendMsg.TransactionID));
                            m_statistics.IncRetransmission();
                        }
                        else
                        {
                            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("Failed! Join {0} TransId={1:x16}", m_ReloadConfig.AdmittingPeer, reloadSendMsg.TransactionID));
                            m_statistics.IncTransmissionError();
                        }
                    }

                    try
                    {
                        if (!reloadDialog.Error)
                        {
                            reloadRcvMsg = reloadDialog.ReceivedMessage;
                            RELOAD_MessageCode msgCode = reloadRcvMsg.reload_message_body.RELOAD_MsgCode;
                            if (reloadRcvMsg != null)
                            {
                                if (msgCode == RELOAD_MessageCode.Join_Answer)
                                {
                                    m_topology.routing_table.SetWaitForJoinAnsw(reloadRcvMsg.OriginatorID, false);

                                    m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD,
                                      String.Format("{0} <== {1} TransId={2:x16}",
                                      msgCode.ToString().PadRight(16, ' '), reloadRcvMsg.OriginatorID,
                                      reloadRcvMsg.TransactionID));

                                    NodeState nodestate = m_topology.routing_table.GetNodeState(reloadRcvMsg.OriginatorID);

                                    if (nodestate == NodeState.updates_received)
                                    {
                                        /* we previously received an update from admitting peer (maybe 
                                         * race condition), now joining is complete in any other case 
                                         * wait for updates to come from this node */
                                        m_ReloadConfig.State = ReloadConfig.RELOAD_State.Joined;
                                        m_machine.StateUpdates(ReloadConfig.RELOAD_State.Joined);
                                        m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("Joining completed"));
                                        m_ReloadConfig.LastJoinedTime = DateTime.Now;
                                        TimeSpan joiningTime = m_ReloadConfig.LastJoinedTime - m_ReloadConfig.StartJoining;
                                        m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_MEASURE, String.Format("Join:{0}", joiningTime.TotalSeconds.ToString()));

                                        m_topology.routing_table.SendUpdateToAllNeighbors();
                                    }
                                    else
                                    {
                                        m_ReloadConfig.LastJoinedTime = DateTime.Now;
                                        TimeSpan joiningTime = m_ReloadConfig.LastJoinedTime - m_ReloadConfig.StartTime;
                                        m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_MEASURE, String.Format("Join:{0}", joiningTime.TotalSeconds.ToString()));

                                        m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_WARNING,
                                          String.Format("Prejoin: nodestate != update_recv at Node {0}", m_machine.ReloadConfig.ListenPort));
                                    }
                                    //m_topology.routing_table.SendUpdatesToAllFingers();
                                }
                            }
                            else
                            {
                                m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "PreJoinProcedure: reloadRcvMsg == null!!");
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "PreJoinProcedure: " + ex.Message);
                    }
                }
                else
                {
                    if (m_ReloadConfig.SipUri == "")
                        m_ReloadConfig.SipUri = String.Format("{0}@{1}", ReloadGlobals.HostName,
                            m_ReloadConfig.OverlayName);

                    if (m_ReloadConfig.SipUri != null && m_ReloadConfig.SipUri != "")
                    {
                        // explictite SIP registration as minimal config for RELOAD clients

                        IUsage sipRegistration = m_machine.UsageManager.CreateUsage(Usage_Code_Point.SIP_REGISTRATION,
                                                                         2,
                                                                         m_ReloadConfig.SipUri);
                        sipRegistration.ResourceName = m_ReloadConfig.SipUri;
                        List<StoreKindData> clientRegistrationList = new List<StoreKindData>();
                        StoreKindData sipKindData = new StoreKindData(sipRegistration.KindId,
                                                                      0, new StoredData(sipRegistration.Encapsulate(true)));
                        clientRegistrationList.Add(sipKindData);
                        Arbiter.Activate(m_DispatcherQueue, new IterativeTask<string, List<StoreKindData>>(m_ReloadConfig.SipUri, clientRegistrationList, Store));
                    }
                }
            else
            {
                m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_MEASURE,
                  String.Format("PreJoinPredure => Node {0} has no admitting peer = {1}!",
                  m_machine.ReloadConfig.ListenPort, m_ReloadConfig.AdmittingPeer));
                if (ReloadGlobals.AutoExe)
                {
                    m_machine.SendCommand("Exit");
                }
            }
        } // End PreJoin        
Ejemplo n.º 2
0
        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);
            }
        }
Ejemplo n.º 3
0
        public IEnumerator<ITask> AppAttachProcedure(Destination dest)
        {
            ReloadMessage reloadSendMsg;

            reloadSendMsg = create_app_attach_req(dest);

            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);

            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()));
                            /* 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;
                            if (AppAttachDone != null) appAttachDone.Post(answ.ice_candidates[0]);
                            if (ReloadGlobals.AutoExe)
                            {
                                TimeSpan appAttachTime = DateTime.Now - m_ReloadConfig.StartFetchAttach;
                                m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_MEASURE, String.Format("Fetch:{0}", appAttachTime.TotalSeconds));
                            }
                        }
                    }
                    else if (reloadRcvMsg.reload_message_body.RELOAD_MsgCode == RELOAD_MessageCode.Error)
                    {
                        // TODO
                    }
                }
                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);
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// The Fetch request retrieves one or more data elements stored at a
        /// given Resource-ID.  A single Fetch request can retrieve multiple
        /// different kinds.
        /// 
        /// RELOAD base -13 p.92
        /// --alex
        /// </summary>
        /// <param name="resourceName">The resouces name (human readable)</param>
        /// <param name="specifiers">StoredSpecifier objects</param>
        /// <returns></returns>
        public IEnumerator<ITask> Fetch(string resourceName, List<StoredDataSpecifier> specifiers)
        {
            ReloadDialog reloadDialog = null;
            ReloadMessage reloadSendMsg;
            List<IUsage> recUsages = new List<IUsage>();
            ResourceId res_id = new ResourceId(resourceName);

            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR,
                String.Format("Fetch {0} as ResID: {1}", resourceName, res_id));

            Node 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));
            List<FetchKindResponse> fetchKindResponses = new List<FetchKindResponse>();
            FetchKindResponse fetchKindResponse = null;

            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_ERROR, "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_ERROR,
                      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;

                        // TODO: For now add certificate to global PKC Store, but they are only temporarilly needed in validateDataSignature
                        m_ReloadConfig.AccessController.SetPKCs(reloadRcvMsg.security_block.Certificates);

                        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);
            }
        }
Ejemplo n.º 5
0
        public IEnumerator<ITask> SendUpdate(Node node, Node nexthopnode)
        {
            ReloadDialog reloadDialog = null;
            ReloadMessage reloadSendMsg;

            /*if (m_topology.routing_table.isFinger(node.Id))
              m_topology.routing_table.AddFinger(node);*/

            if (nexthopnode == null)
                nexthopnode = node;

            Destination dest = new Destination(node.Id);

            reloadSendMsg = create_update_req(dest, m_topology.routing_table,
              ChordUpdateType.neighbors);

            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, nexthopnode);

                    m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD,
                      String.Format("{0} ==> {1} TransId={2:x16}",
                      RELOAD_MessageCode.Update_Request.ToString().PadRight(16, ' '),
                      node.Id, reloadSendMsg.TransactionID));
                    //m_ReloadConfig.start
                    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 Update: " + ex.Message);
                    yield break;
                }

                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;
                if (iRetrans > 0)
                {
                    m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_WARNING,
                      String.Format("Retrans {0} SendUpdate  {1}:{2} TransId={3:x16}",
                      iRetrans, node, nexthopnode, reloadSendMsg.TransactionID));
                    m_statistics.IncRetransmission();
                }
                else
                {
                    m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR,
                      String.Format("Failed! SendUpdate  {0}:{1} TransId={2:x16}",
                      node, nexthopnode, reloadSendMsg.TransactionID));
                    m_statistics.IncTransmissionError();
                }
            }

            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 msgCode = reloadRcvMsg.reload_message_body.RELOAD_MsgCode;
                    if (msgCode == RELOAD_MessageCode.Update_Answer)
                    {
                        m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD,
                          String.Format("{0} <== {1} TransId={2:x16}",
                          msgCode.ToString().PadRight(16, ' '), reloadRcvMsg.OriginatorID,
                          reloadRcvMsg.TransactionID));

                        UpdateReqAns answ = (UpdateReqAns)reloadRcvMsg.reload_message_body;

                        if (answ != null)
                        {
                            NodeId originator = reloadRcvMsg.OriginatorID;

                            if (m_topology.routing_table.FingerSuccessors.Contains(originator))
                            {
                                //m_topology.routing_table.GetNode(originator).Successors = answ.Successors;
                                //m_topology.routing_table.GetNode(originator).Predecessors = answ.Predecessors;
                                m_topology.routing_table.SetFingerState(originator,
                                  NodeState.updates_received);
                            }
                            if (m_topology.routing_table.RtTable.ContainsKey(originator.ToString()))
                            {
                                m_topology.routing_table.SetNodeState(originator,
                                  NodeState.updates_received);
                                m_topology.routing_table.GetNode(originator).Successors = answ.Successors;
                                m_topology.routing_table.GetNode(originator).Predecessors = answ.Predecessors;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR,
                  "Send Update: " + ex.Message);
            }
        }
Ejemplo n.º 6
0
        /// <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);
                    }
                }
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Handover key if: 1. leave overlay 2. I'm AP while a join req happens.
        /// </summary>
        /// <param name="fSendLeaveFirst"></param>
        /// <returns></returns>
        public IEnumerator<ITask> HandoverKeys(bool fSendLeaveFirst)
        {
            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TOPO, "Handover Keys!");

            if (fSendLeaveFirst)
            {
                yield return Arbiter.ExecuteToCompletion(m_DispatcherQueue, new IterativeTask(Leave));
            }

            // 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>>();

                Dictionary<ResourceId, Node> destinations = new Dictionary<ResourceId, Node>();

                foreach (string key in storedKeys)
                {
                    ResourceId res_id = new ResourceId(ReloadGlobals.HexToBytes(key));
                    Node currentNode = m_topology.routing_table.FindNextHopTo(new NodeId(res_id), true, fSendLeaveFirst);
                    if (currentNode == null || currentNode.Id == m_ReloadConfig.LocalNodeID)
                    {
                        //everything's fine, key still belongs to me
                        continue;
                    }
                    // REPLICATEST
                    // peer is no longer in the replica set for the resource
                    else if (m_topology.routing_table.Predecessors.Count > 2 && !res_id.ElementOfInterval(m_topology.routing_table.Predecessors[2], m_topology.LocalNode.Id, false))
                    {
                        m_topology.Storage.Remove(res_id.ToString());
                        m_topology.Replicas.Remove(res_id.ToString());
                        m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ALL, String.Format("Data {0} no longer in range. Delete replica", res_id.ToString()));
                    }
                    else
                    {
                        if (!m_topology.Replicas.Contains(key))
                        {
                            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TOPO, "Handover Keys - 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));

                                destinations.Add(res_id, currentNode);
                            }
                            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)
                {
                    Node node = destinations[res_id];
                    storeKindData = nodes[res_id];

                    List<SignerIdentity> signers = new List<SignerIdentity>();

                    m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TOPO, "GOING TO STORE UNDER RES_ID: " + res_id);

                    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);
                        }
                    }

                    if (m_machine.ReloadConfig.State == ReloadConfig.RELOAD_State.Leave)
                    {
                        node = m_topology.routing_table.GetSuccessor(0);
                        reloadSendMsg = create_store_req(new Destination(node.Id), res_id, storeKindData, false);
                    }
                    else
                    {
                        reloadSendMsg = create_store_req(new Destination(res_id), storeKindData, false);
                    }

                    // 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, 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)
                        {
                            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)
                                {
                                    // m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_WARNING, String.Format("Delete Key {0}", res_id));
                                    // m_topology.StoredValues.Remove(StoredKey); --old

                                    // REPLICATEST
                                    // Keep stored data but mark it as replica
                                    if (!m_topology.Replicas.Contains(res_id.ToString()))
                                        m_topology.Replicas.Add(res_id.ToString());

                                    //m_topology.Storage.Remove(res_id.ToString());
                                }
                            }
                        }
                        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: " + ex.Message);
                    }
                }
            }

            // this code might be redundant to code in RoutingTable.Leave()

            //// check if there are replicas I should be responsible for
            //if (m_topology.routing_table.Predecessors.Count == 0)
            //{
            //    m_topology.Replicas.Clear();
            //}
            //else
            //{
            //    List<string> removeReplicas = new List<string>();
            //    foreach (string replica in m_topology.Replicas)
            //    {
            //        // Convert the Resource String in a ResourceId
            //        int NumberChars = replica.Length;
            //        byte[] bytes = new byte[NumberChars / 2];
            //        for (int i = 0; i < NumberChars; i += 2)
            //            bytes[i / 2] = Convert.ToByte(replica.Substring(i, 2), 16);
            //        ResourceId id = new ResourceId(bytes);

            //        if (id.ElementOfInterval(m_topology.routing_table.Predecessors[0], m_topology.LocalNode.Id, false))
            //        {
            //            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ALL, String.Format("ResId: {0} is in interval [{1} - {2}]", id, m_topology.routing_table.Predecessors[0], m_topology.LocalNode.Id));
            //            removeReplicas.Add(replica);
            //        }
            //    }
            //    foreach (string removeRep in removeReplicas)
            //    {
            //        m_topology.Replicas.Remove(removeRep);
            //        Arbiter.Activate(m_ReloadConfig.DispatcherQueue, new IterativeTask<NodeId>(m_topology.routing_table.Successors[0], StoreReplicas));
            //        if(m_topology.routing_table.Successors.Count > 1)
            //            Arbiter.Activate(m_ReloadConfig.DispatcherQueue, new IterativeTask<NodeId>(m_topology.routing_table.Successors[1], StoreReplicas));
            //    }
            //}

            if (m_ReloadConfig.State == ReloadConfig.RELOAD_State.Leave)
                m_machine.SendCommand("Exit");

            if (fSendLeaveFirst)
                //this will reset neighbor tables
                m_topology.Leave();
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Just the leaving Procedure
        /// </summary>
        /// <returns></returns>
        public IEnumerator<ITask> Leave()
        {
            m_ReloadConfig.State = ReloadConfig.RELOAD_State.Leave;

            foreach (ReloadConnectionTableInfoElement rce in m_flm.ConnectionTable)
            {

                if (m_topology.routing_table.RtTable.ContainsKey(rce.NodeID.ToString()))
                {

                    ReloadDialog reloadDialog = null;
                    ReloadMessage reloadSendMsg = create_leave_req(new Destination(rce.NodeID));

                    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.GetNode(rce.NodeID));

                            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD,
                              String.Format("{0} ==> {1} TransId={2:x16}",
                              reloadSendMsg.reload_message_body.RELOAD_MsgCode.ToString().PadRight(16, ' '),
                              rce.NodeID, 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 Leave: " + ex.Message);
                        }

                        if (reloadDialog != null)
                        {
                            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 code = reloadRcvMsg.reload_message_body.RELOAD_MsgCode;
                            if (code == RELOAD_MessageCode.Leave_Answer)
                            {
                                m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD,
                                  String.Format("{0} <== {1} TransId={2:x16}",
                                  code.ToString().PadRight(16, ' '), reloadRcvMsg.OriginatorID,
                                  reloadRcvMsg.TransactionID));
                            }
                        }
                        else
                        {
                            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_WARNING,
                              String.Format("Leave failed"));
                            m_statistics.IncTransmissionError();
                        }
                    }
                    catch (Exception ex)
                    {
                        m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR,
                          "Send Leave: " + ex.Message);
                    }
                }
            }

            //m_machine.SendCommand("Exit");

            // Arbiter.Activate(m_DispatcherQueue, new IterativeTask<ReloadMessage, Node>(reloadSendMsg, m_topology.routing_table.GetNode(rce.NodeID), Send));
            // m_ReloadConfig.State = ReloadConfig.RELOAD_State.PreJoin;
            // m_machine.StateUpdates(ReloadConfig.RELOAD_State.PreJoin);
        }
Ejemplo n.º 9
0
        // --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();

        }
Ejemplo n.º 10
0
        public IEnumerator<ITask> SendPing(Destination dest, PingOption pingOption)
        {
            ReloadDialog reloadDialog = null;
            ReloadMessage reloadSendMsg;

            reloadSendMsg = create_ping_req(dest);

            int RetransmissionTime = ReloadGlobals.RetransmissionTime + ReloadGlobals.MaxTimeToSendPacket;

            Boolean NextHopIsDestination = false;
            Node NextHopNode = NextHopToDestination(dest, ref NextHopIsDestination);

            if (NextHopNode == null)
                yield break;

            if (NextHopNode.Id == m_topology.LocalNode.Id)
                yield break;

            if (dest.type == DestinationType.node)
            {
                /* This code assumes, that a node we want to ping is already attached and added to the routing table */
                NodeState nodestate = m_topology.routing_table.GetNodeState(dest.destination_data.node_id);
                bool pinging = m_topology.routing_table.GetPing(dest.destination_data.node_id);

                if (((pingOption & PingOption.standard | PingOption.finger) != 0) && nodestate == NodeState.unknown && !pinging)
                {
                    m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("Ignoring redundant Ping for {0}", dest));
                    yield break;
                }
                m_topology.routing_table.SetPinging(dest.destination_data.node_id, true, false);
            }
            else if (!NextHopIsDestination && ((pingOption & PingOption.direct) != 0))
            {
                m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("Direct Ping for {0} ignored, no entry in routing table", dest));
                yield break;
            }


            /* Don't spend too much time on connectivity checks */
            int iRetrans = 3;

            while (iRetrans > 0 && m_ReloadConfig.State < ReloadConfig.RELOAD_State.Shutdown)
            {
                try
                {
                    reloadDialog = new ReloadDialog(m_ReloadConfig, m_flm, NextHopNode);

                    m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("{0} ==> {1} TransId={2:x16}",
                        reloadSendMsg.reload_message_body.RELOAD_MsgCode.ToString().PadRight(16, ' '), NextHopNode.Id, 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 Ping: " + ex.Message);
                    yield break;
                }

                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
            {
                PingReqAns answ = null;

                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;

                    if (reloadRcvMsg.reload_message_body.RELOAD_MsgCode == RELOAD_MessageCode.Ping_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));

                        answ = (PingReqAns)reloadRcvMsg.reload_message_body;

                        if (answ != null)
                        {
                            if ((pingOption & PingOption.finger) != 0)
                            {
                                foreach (Topology.TopologyPlugin.RoutingTable.FTableEntry fte in m_topology.routing_table.FingerTable)
                                {
                                    if (fte.Finger == dest.destination_data.ressource_id)
                                    {
                                        fte.dtLastSuccessfullFinger = DateTime.Now;
                                        fte.Successor = reloadRcvMsg.OriginatorID;
                                        fte.pinging = true;
                                    }
                                }

                                /* Attach if not attached */
                                if (!m_topology.routing_table.IsAttached(reloadRcvMsg.OriginatorID))
                                    Arbiter.Activate(m_DispatcherQueue,
                                        new IterativeTask<Destination, NodeId, AttachOption>(new Destination(reloadRcvMsg.OriginatorID),
                                            reloadRcvMsg.LastHopNodeId,
                                            AttachOption.sendping,
                                            AttachProcedure));
                                else if (reloadRcvMsg.OriginatorID != reloadRcvMsg.LastHopNodeId)// Send ping to get/keep a physical connection
                                    Arbiter.Activate(m_DispatcherQueue, new IterativeTask<Destination, PingOption>(new Destination(reloadRcvMsg.OriginatorID), PingOption.direct, SendPing));
                            }
                        }
                    }
                }
                else
                {
                    if (dest.type == DestinationType.node)
                    {
                        m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_WARNING, String.Format("Ping failed: removing node {0}", dest.destination_data.node_id));
                        m_topology.routing_table.Leave(dest.destination_data.node_id);
                    }
                    m_statistics.IncTransmissionError();
                }

                if (dest.type == DestinationType.node)
                    m_topology.routing_table.SetPinging(dest.destination_data.node_id, false, answ != null);
            }
            catch (Exception ex)
            {
                m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "Send Ping: " + ex.Message);
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Stores the Usage data in the RELOAD overlay
        /// </summary>
        /// <param name="ResourceName"></param>
        /// <param name="DestUrl"></param>
        /// <param name="exists">if true, stores the values, else stores a "non-existent" value.</param>
        /// <param name="usages">The Usage data to be stored.</param>
        /// <returns></returns>        
        public IEnumerator<ITask> Store(string ResourceName, List<StoreKindData> kind_data)
        {
            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);

            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_USAGE, String.Format("Store {0} as ResID: {1}", ResourceName, res_id));
            Node 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);
                }

                // REPLICATEST
                // incoming store request is not a replication request
                int numberReplicas = m_topology.routing_table.Successors.Count >= 2 ? 2 : m_topology.routing_table.Successors.Count; // Replica number is max 2
                // send replica to all successors
                for (int i = 0; i < numberReplicas; i++)
                {
                    NodeId successorNode = m_topology.routing_table.Successors[i];
                    ReloadMessage replica = create_store_req(new Destination(successorNode), res_id, kind_data, true);
                    send(replica, m_topology.routing_table.GetNode(successorNode));
                }

                if (storeDone != null) storeDone.Post(reloadDialog);
                yield break;
            }

            Destination dest = new Destination(res_id);

            reloadSendMsg = create_store_req(dest, 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);
                    break;
                }

                yield return Arbiter.Receive(false, reloadDialog.Done, done => { });

                //if (!reloadDialog.Error && reloadDialog.ReceivedMessage != null && reloadDialog.ReceivedMessage.reload_message_body.RELOAD_MsgCode == RELOAD_MessageCode.Store_Answer)
                //    break;

                if (!reloadDialog.Error && reloadDialog.ReceivedMessage != null && reloadDialog.ReceivedMessage.reload_message_body.RELOAD_MsgCode == RELOAD_MessageCode.Store_Answer)
                {

                    ReloadMessage reloadRcvMsg = reloadDialog.ReceivedMessage;

                    if (dest.type == DestinationType.node)
                    {
                        if (reloadRcvMsg.OriginatorID != dest.destination_data.node_id)
                        {
                            // drop message and retransmit request
                            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
                                    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;
            }

            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();

        }
Ejemplo n.º 12
0
        } // End PreJoin        

        /// <summary>
        /// Attaches to a node needed to enrich the finger table.
        /// </summary>
        /// <param name="finger"></param>    
        /// <returns></returns>
        public IEnumerator<ITask> AttachFinger(FTEntry finger,
          Port<bool> attachNext)
        {
            Destination dest = new Destination(finger.Finger);
            ReloadMessage reloadSendMsg = create_attach_req(dest, false);
            ReloadDialog reloadDialog = null;

            int RetransmissionTime = ReloadGlobals.RetransmissionTime +
              ReloadGlobals.MaxTimeToSendPacket;
            int iRetrans = ReloadGlobals.MaxRetransmissions;

            Boolean NextHopIsDestination = false;
            var myNodeId = m_topology.LocalNode.Id;
            Node nextHopNode = NextHopToDestination(dest, ref NextHopIsDestination);

            if (nextHopNode == null ||
              nextHopNode.Id == m_ReloadConfig.LocalNodeID)
                nextHopNode = m_ReloadConfig.AdmittingPeer;

            if (nextHopNode == null) //{
                m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR,
                String.Format("No Route to Finger! {0}", finger.Finger));
            //attachNext.Post(true);
            // yield break;
            //}
            //else {
            while (iRetrans >= 0 && m_ReloadConfig.State < ReloadConfig.RELOAD_State.Shutdown)
            {
                try
                {
                    reloadDialog = new ReloadDialog(m_ReloadConfig, m_flm, nextHopNode);
                    m_forwarding.LoopedTrans = new Port<UInt64>();
                    if (reloadDialog == null)
                        m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD,
                        "ReloadDialog null!");

                    m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TOPO,
                      String.Format("Finger-{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 e)
                {
                    m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR,
                      String.Format("AttachFinger: " + e));
                    attachNext.Post(true);
                    yield break;
                }
                bool gotLoop = false;

                yield return Arbiter.Choice(
                    /* Success, Attached to finger */
                  Arbiter.Receive(false, reloadDialog.Done, done => { }),
                    /* Loop detected */
                  Arbiter.Receive(false, m_forwarding.LoopedTrans, transId =>
                  {
                      if (transId == reloadSendMsg.TransactionID)
                      {
                          m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR,
                            String.Format("Not re-sending transaction: {0:x16}=> a loopback detected!",
                            reloadSendMsg.TransactionID));
                          gotLoop = true;
                          m_forwarding.LoopedTrans = new Port<ulong>();
                      }
                  }));


                if (gotLoop)
                {
                    attachNext.Post(true);
                    yield break; ;
                }

                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;
                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);
                }
                // }
            }

            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 = null;
                    if (msgCode == RELOAD_MessageCode.Attach_Answer)
                    {
                        answ = (AttachReqAns)reloadRcvMsg.reload_message_body;

                        m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TOPO,
                          String.Format("Finger-{0} <== {1} TransId={2:x16}",
                          msgCode.ToString().PadRight(16, ' '),
                          reloadRcvMsg.OriginatorID, reloadRcvMsg.TransactionID));

                        Node originator = new Node(reloadRcvMsg.OriginatorID, answ.ice_candidates);
                        NodeState nodeState = m_topology.routing_table.GetNodeState(originator.Id);
                        if (nodeState == NodeState.unknown)
                        {
                            attachNext.Post(true);
                            m_topology.routing_table.AddNode(originator);
                            m_topology.routing_table.SetNodeState(originator.Id, NodeState.attached);
                            m_topology.routing_table.AddFinger(originator, NodeState.attached);
                            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_USAGE,
                              String.Format("Got a finger! {0}", originator.Id));
                        }
                        /* we know this peer, further Attaches will return same peer */
                        else
                            attachNext.Post(false);
                    }
                }
            }
            catch (Exception e)
            {
                m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR,
                  String.Format("AttachFingers:" + e));
            }
        }