ToString() public method

public ToString ( ) : string
return string
Exemplo 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        
Exemplo 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);
            }
        }
Exemplo 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);
            }
        }
Exemplo n.º 4
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));
            }
        }