Node maintenance uses this object
Exemple #1
0
 /// <summary>
 /// Inits the Usage Manager.
 /// </summary>
 /// <param name="machine">The state machine for RELOAD overlay.</param>
 public void Init(Machine machine) {
   localNode = machine.Topology.LocalNode;
   m_Transport = machine.Transport;
   m_ReloadConfig = machine.ReloadConfig;
   m_DispatcherQueue = machine.ReloadConfig.DispatcherQueue;
   usages = new Dictionary<Usage_Code_Point, IUsage>();
   m_ArrayManager = new ArrayManager();
 }
Exemple #2
0
        public ReloadDialog(ReloadConfig reloadConfig, IForwardLinkManagement transport, Node nexthopnode) {
            this.m_NextHopNode = nexthopnode;
            this.m_Transport = transport;
            this.m_fDone = new Port<bool>();
            this.m_DispatcherQueue = reloadConfig.DispatcherQueue;
            this.m_ReloadConfig = reloadConfig;
            m_Transport.ReloadFLMEventHandler += new ReloadFLMEvent(OVL_ReloadForwardLinkManagementEventHandler);

            if(nexthopnode.IceCandidates == null)
                throw new System.Exception(String.Format("ReloadDialog: no ice candidates for {0} ", nexthopnode.Id));
        }
Exemple #3
0
 public IEnumerator<ITask> Send(ReloadMessage reloadSendMsg, Node NextHopNode)
 {
     if (reloadSendMsg.reload_message_body.RELOAD_MsgCode ==
       RELOAD_MessageCode.Error)
         m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR,
           String.Format("{0} ==> {1} code={2}: msg=\"{3}\", dest={4}",
           reloadSendMsg.reload_message_body.RELOAD_MsgCode.ToString().PadRight(16, ' '),
           NextHopNode, ((ErrorResponse)reloadSendMsg.reload_message_body).ErrorCode,
           ((ErrorResponse)reloadSendMsg.reload_message_body).ErrorMsg,
           reloadSendMsg.forwarding_header.destination_list[0]));
     try
     {
         Arbiter.Activate(m_DispatcherQueue, new IterativeTask<Node, ReloadMessage>(NextHopNode, reloadSendMsg, GetForwardingAndLinkManagementLayer().Send));
     }
     catch (Exception ex)
     {
         m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR,
           "SendAnswer: " + ex.Message);
     }
     yield break;
 }
Exemple #4
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);
            }
        }
Exemple #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);
            }
        }
Exemple #6
0
    public IEnumerator<ITask> Send(Node node, byte[] buffer) {
      Socket socket = null;
      SimpleOverlayConnectionTableElement socte = null;

#if false
            /* paranoia: check validity of buffer here again */
            if (   buffer[0] != 0xC2
                && buffer[1] != 0x45
                && buffer[2] != 0x4c
                && buffer[3] != 0x4f)
            {
                m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "SimpleFLM: Wrong Tag in Send message!");
                yield break;
            }
#endif

#if CONNECTION_MANAGEMENT
      /* beginn connection management */
      lock (m_connection_table) {
        if (node.Id != null && m_connection_table.ContainsKey(node.Id.ToString())) {
          SimpleOverlayConnectionTableElement el = m_connection_table[node.Id.ToString()];

          if (el.NodeID == node.Id) {
            if (el.AssociatedSocket.Connected) {
              long offset = 0;
              socket = el.AssociatedSocket;
              try {
                ReloadMessage reloadMsg = new ReloadMessage(m_ReloadConfig).FromBytes(buffer, ref offset, ReloadMessage.ReadFlags.no_certcheck);
                m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_SOCKET, String.Format("SimpleFLM: >> {0} {1} ==> {2}, TransID={3:x16}", socket.RemoteEndPoint, reloadMsg.reload_message_body.RELOAD_MsgCode.ToString(), node.Id.ToString(), reloadMsg.TransactionID));
                socte = el;
              }
              catch (Exception ex) {
                m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR,
                  String.Format("SimpleFLM Send: {0}", ex.Message));
              }
            }
            else {
              // no longer connected, remove entry
              m_connection_table.Remove(node.Id.ToString());
              m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_SOCKET, String.Format("SimpleFLM: >> {0} removed, associated with {1}", el.AssociatedSocket, node.Id.ToString()));
            }
          }
        }
      }
      /* end connection management */
#endif

      if (socket == null) {
        if (node.IceCandidates != null) {
          /*                  if (node.Id != null)
                              {
                                  ReloadMessage reloadMsg = new ReloadMessage().FromBytes(buffer);
                                  m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TEST, String.Format("SimpleFLM: {0} ==> {1} TransID={2:x16}", reloadMsg.reload_message_body.RELOAD_MsgCode.ToString(), node.Id.ToString(), reloadMsg.TransactionID));
                              }
          */
          foreach (IceCandidate candidate in node.IceCandidates) {
            switch (candidate.addr_port.type) {
              case AddressType.IPv6_Address:
              case AddressType.IPv4_Address: {
                  if (socket == null) {
                    socket = new Socket(candidate.addr_port.ipaddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

                    var iarPort = new Port<IAsyncResult>();
                    socket.BeginConnect(new IPEndPoint(candidate.addr_port.ipaddr, candidate.addr_port.port), iarPort.Post, null);

                    yield return Arbiter.Receive(false, iarPort, iar => {
                      try {
                        socket.EndConnect(iar);
                      }
                      catch (Exception ex) {
                        m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "SimpleFLM: Send Connect: " + ex.Message);
                        HandleRemoteClosing(socket);
                        if (socket.Connected)
                          socket.Shutdown(SocketShutdown.Both);
                        socket.Close();
                        socket = null;
                        return;
                      }
                    });
                  }
                }
                break;
            }
            //just support one ice candidate only here
            break;
          }
        }
        else {
          long offset = 0;
          ReloadMessage reloadMsg = new ReloadMessage(m_ReloadConfig).FromBytes(buffer, ref offset, ReloadMessage.ReadFlags.no_certcheck);
          m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("SimpleFLM: {0} ==> {1} TransID={2:x16} (No ice candidates and no connection!)", reloadMsg.reload_message_body.RELOAD_MsgCode.ToString(), node.Id.ToString(), reloadMsg.TransactionID));
          m_ReloadConfig.Statistics.IncConnectionError();
        }
      }

      if (socket != null) {
        m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_SOCKET,
          String.Format("SimpleFLM: >> {0} Send {1} bytes",
          socket.RemoteEndPoint, buffer.Length));

        var iarPort2 = new Port<IAsyncResult>();

        socte = new SimpleOverlayConnectionTableElement();

        byte[] framed_buffer = addFrameHeader(socte, buffer);

        socket.BeginSend(framed_buffer, 0, framed_buffer.Length,
          SocketFlags.None, iarPort2.Post, null);

        m_ReloadConfig.Statistics.BytesTx = (UInt64)framed_buffer.Length;

        yield return Arbiter.Receive(false, iarPort2, iar => {
          try {
            socket.EndSend(iar);
          }
          catch (Exception ex) {
            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR,
              "SimpleFLM: SocketError : " + ex.Message);
            m_ReloadConfig.Statistics.IncConnectionError();
          }
        });

#if CONNECTION_MANAGEMENT

        if (socket.Connected) {
          /* beginn connection management */

          lock (m_connection_table) {
            if (node.Id != null && node.Id != m_ReloadConfig.LocalNodeID)
              if (m_connection_table.ContainsKey(node.Id.ToString())) {
                SimpleOverlayConnectionTableElement rcel = m_connection_table[node.Id.ToString()];
                rcel.LastActivity = DateTime.Now;
              }
              else {
                SimpleOverlayConnectionTableElement rcel = new SimpleOverlayConnectionTableElement();
                rcel.NodeID = node.Id;
                rcel.AssociatedSocket = socket;
                rcel.LastActivity = rcel.Start = DateTime.Now;
                rcel.Outbound = true;

                m_connection_table.Add(rcel.NodeID.ToString(), rcel);
                m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_SOCKET, String.Format("SimpleFLM: >> {0} Send: Associating node {1}", socket.RemoteEndPoint, rcel.NodeID.ToString()));
                Arbiter.Activate(m_ReloadConfig.DispatcherQueue, new IterativeTask<Socket, NodeId>(socket, node.Id, Receive));
              }
          }
          if (node.Id == null) {
            Arbiter.Activate(m_ReloadConfig.DispatcherQueue, new IterativeTask<Socket, NodeId>(socket, node.Id, Receive));
          }
        }
        else {
          m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "SimpleFLM: Socket not connected after send");
        }
        /* end connection management */
#else
                if(socket.Connected)
                    socket.Shutdown(SocketShutdown.Both);
                socket.Close();
#endif
      }
    }
Exemple #7
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);
            }
        }
Exemple #8
0
        public void reload_app_attach_inbound(ReloadMessage recmsg)
        {
            AppAttachReqAns req_answ = (AppAttachReqAns)recmsg.reload_message_body;
            NodeId OriginatorID = recmsg.OriginatorID;
            Node Originator = new Node(recmsg.OriginatorID, req_answ.ice_candidates);

            m_topology.routing_table.AddNode(Originator);
            m_topology.routing_table.SetNodeState(Originator.Id, NodeState.attached);

            //Proprietary --joscha
            string destination_overlay = null;
            string source_overlay = null;

            if (recmsg.forwarding_header.fw_options != null)
            {

                foreach (ForwardingOption option in recmsg.forwarding_header.fw_options)
                {
                    if (option.fwo_type == ForwardingOptionsType.destinationOverlay)
                    {
                        destination_overlay = System.Text.Encoding.Unicode.GetString(option.bytes);
                        m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("{0} Message  for destinationOverlay=" + destination_overlay, recmsg.reload_message_body.RELOAD_MsgCode));
                    }
                    if (option.fwo_type == ForwardingOptionsType.sourceOverlay)
                    {
                        source_overlay = System.Text.Encoding.Unicode.GetString(option.bytes);
                        m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("Message from sourceOverlay=" + source_overlay));
                    }
                }
            }

            if (destination_overlay == null)// --joscha Do not establish a connection to a different overlay    
                if (CheckAndSetAdmittingPeer(Originator) && Originator.Id != recmsg.LastHopNodeId)
                    // Send ping to establish a physical connection
                    Arbiter.Activate(m_DispatcherQueue,
                      new IterativeTask<Destination, PingOption>(new Destination(Originator.Id),
                      PingOption.direct, SendPing));

            if (source_overlay == m_ReloadConfig.OverlayName)
            {

                // Send ping to establish a physical connection
                Arbiter.Activate(m_DispatcherQueue,
                  new IterativeTask<Destination, PingOption>(new Destination(Originator.Id),
                  PingOption.direct, SendPing));
            }
            if (req_answ != null && req_answ.ice_candidates != null)
            {
                if (recmsg.IsRequest())
                {

                    m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("transport.cs - reload_app_attach_inbound"));

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

                    ReloadMessage sendmsg = create_app_attach_answ(
                      new Destination(OriginatorID), recmsg.TransactionID);
                    recmsg.PutViaListToDestination(sendmsg);
                    //sendmsg.addOverlayForwardingOptions(recmsg);  //--joscha
                    send(sendmsg, m_topology.routing_table.GetNode(recmsg.LastHopNodeId));
                }
                else
                {
                    m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("{0} <== {1} (not handled!!)", req_answ.RELOAD_MsgCode.ToString().PadRight(16, ' '), OriginatorID));
                }
            }
        }
Exemple #9
0
            public void AddNode(Node node) {
                try {
                    String nodestr = node.Id.ToString();
                    lock (m_RtTable) {
                        if (!m_RtTable.ContainsKey(nodestr) &&
                          node.Id != m_local_node.Id) {
                            /* 
                             * important! we currently assume, that this function is called
                             * in context of attach ans, with exchanged ice 
                             * candidates in any other case attached should not be set to
                             * true. The flag attached signals that this node 
                             * can be part of the official successor/predecessor list
                             */
                            m_RtTable.Add(nodestr, new RTableEntry()
                            {
                                icecandidates = node.IceCandidates,
                                dtLastSuccessfullPing = DateTime.MinValue,
                                nodestate = NodeState.unknown,
                                node = node
                            });

                            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO,
                              String.Format("AddNode: {0}", node));
                        }
                    }
                }
                catch (Exception ex) {
                    m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR,
                      "Topology.AddNode: " + ex.Message);
                }

                /*Is a finger?*/
                if (isFinger(node.Id))
                    AddFinger(node, NodeState.attached);
            }
Exemple #10
0
 public AppAttachReqAns(Node chordnode, bool req)
 {
     RELOAD_MsgCode = req ? RELOAD_MessageCode.App_Attach_Request : RELOAD_MessageCode.App_Attach_Answer;
     ice_candidates = chordnode.IceCandidates;
 }
Exemple #11
0
        public AttachReqAns(Node chordnode, bool req, bool send_update, bool isBootstrap, bool gatherActiveHostOnly) // markus: chordnode is always m_topology.LocalNode 
        // markus, also check if localnode is a bootstrap
        {
            RELOAD_MsgCode = req ? RELOAD_MessageCode.Attach_Request : RELOAD_MessageCode.Attach_Answer;

            // markus:
            // ufrag and password
            ufrag = new byte[255];
            password = new byte[255];

            // RFC 5245, ICE, Section 15.4:
            // The ice-ufrag and ice-pwd attributes MUST be chosen randomly at the beginning of a session
            Random random = new Random();
            random.NextBytes(ufrag);
            random.NextBytes(password);


            // NO_ICE                           // markus
            if (ReloadGlobals.UseNoIce)
            {
                //ice_candidates = chordnode.IceCandidates;
                ice_candidates = chordnode.NoIceCandidates; // there is only one entry in NoIceCandidates
            }

            // ICE
            else
            {
                if (isBootstrap)
                {
                    IceCandidate bootstrapCandidate = ICE.CreateBootstrapCandidate(chordnode.NoIceCandidates[0].addr_port.ipaddr, chordnode.NoIceCandidates[0].addr_port.port);

                    chordnode.IceCandidates = new List<IceCandidate>();
                    chordnode.IceCandidates.Add(bootstrapCandidate);

                    ice_candidates = chordnode.IceCandidates;
                }

                else
                {
                    List<IceCandidate> iceCandidates = null;

                    if (!gatherActiveHostOnly)
                        // gathering candidates and overwrite localnode candidates
                        iceCandidates = ICE.GatherCandidates();
                    else
                        iceCandidates = ICE.GatherActiveCandidatesForBootstrap();

                    iceCandidates = ICE.PrioritizeCandidates(iceCandidates);
                    chordnode.IceCandidates = ice_candidates = iceCandidates;                       // chordnode is localnode !

                }

            }

            fSendUpdate = send_update;
        }
Exemple #12
0
        public LeaveReqAns(Node leaving_node, bool req)
        {
            RELOAD_MsgCode = req ? RELOAD_MessageCode.Leave_Request : RELOAD_MessageCode.Leave_Answer;

            if (req)
            {
                m_ID = leaving_node.Id;
            }
        }
Exemple #13
0
        public JoinReqAns(Node joining_node, bool req)
        {
            RELOAD_MsgCode = req ? RELOAD_MessageCode.Join_Request : RELOAD_MessageCode.Join_Answer;

            if (req)
            {
                m_ID = joining_node.Id;
            }
        }
Exemple #14
0
        public Boolean CheckAndSetAdmittingPeer(Node node)
        {
            if (!m_ReloadConfig.IsBootstrap)
                if ((m_ReloadConfig.AdmittingPeer == null ||
                     node.Id.ElementOfInterval(m_topology.Id,
                     m_ReloadConfig.AdmittingPeer.Id, true)) &&
                     !(m_ReloadConfig.AdmittingPeer != null &&
                     m_ReloadConfig.AdmittingPeer.Id == node.Id))
                {
                    m_ReloadConfig.AdmittingPeer = node;
                    m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD,
                      String.Format("AttachProcedure: Successfully attached to new" +
                        "admitting peer {0}", m_ReloadConfig.AdmittingPeer.Id));
                    return true;
                }

            return false;
        }
Exemple #15
0
        public bool Init(Machine machine) {
#if false
            Console.Title = String.Format("{3}Node {0}:{1}, ID {2}", ReloadGlobals.HostName, ReloadGlobals.ListenPort, ReloadGlobals.LocalNodeID, ReloadGlobals.SimpleNodeId ? " DEMO " : "");
#endif
            IPAddress Address = null;

            if (ReloadGlobals.HostName != "") {
                Address = ReloadGlobals.IPAddressFromHost(m_ReloadConfig,
                  ReloadGlobals.HostName);
            }
            //TKTEST IETF
           // Address =  new IPAddress(new byte[] { 192, 168, 2, 147 });
            if (Address == null) {
                m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR,
                  "Couldn't figure out my IP Address");
                return false;
            }

            /*use the attach request functionaliy to store 
             * ip-address and port to ice candidates in local node */
            AttachReqAns attreq = new AttachReqAns();
            m_localnode = new Node(m_id, attreq.IPAddressToIceCandidate(
              Address, m_ReloadConfig.ListenPort));

            
            m_localnode.NoIceCandidates = m_localnode.IceCandidates;  // markus: backup of NOICE candidates


            m_routing_table = new RoutingTable(m_localnode, machine);
            m_ReloadConfig.LocalNode = m_localnode;

            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TOPO,
              String.Format("Local node is {0}", m_localnode));

            return true;
        }
Exemple #16
0
        public void reload_attach_inbound(ReloadMessage recmsg)
        {

            try
            {
                AttachReqAns req_answ = (AttachReqAns)recmsg.reload_message_body;
                NodeId OriginatorID = recmsg.OriginatorID;

                if (req_answ != null && req_answ.ice_candidates != null)
                {
                    //if (ReloadGlobals.UseNoIce || m_ReloadConfig.IsBootstrap)
                    //{
                    //Node attacher = new Node(recmsg.OriginatorID, req_answ.ice_candidates);           // markus, moved down
                    //bool isFinger = m_topology.routing_table.isFinger(attacher.Id);

                    //m_topology.routing_table.AddNode(attacher);
                    //m_topology.routing_table.SetNodeState(recmsg.OriginatorID, NodeState.attached);
                    //}


                    // incoming ATTACH REQUEST, so localnode is controlled agent
                    if (recmsg.IsRequest())
                    {

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

                        ReloadMessage sendmsg = create_attach_answ(
                          new Destination(OriginatorID), recmsg.TransactionID);

                        // log output
                        m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("Attach Request: Transaction ID: {0:x}", recmsg.TransactionID));

                        foreach (IceCandidate cand in ((AttachReqAns)sendmsg.reload_message_body).ice_candidates)
                            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("Attach Request: Gathered local candidate for Answer: {0}:{1} (TransId: {2:x})", cand.addr_port.ipaddr.ToString(), cand.addr_port.port, sendmsg.TransactionID));

                        foreach (IceCandidate cand in req_answ.ice_candidates)
                            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("Attach Request: Received remote candidate: {0}:{1} (TransId: {2:x})", cand.addr_port.ipaddr.ToString(), cand.addr_port.port, recmsg.TransactionID));


                        recmsg.PutViaListToDestination(sendmsg);
                        //sendmsg.addOverlayForwardingOptions(recmsg);  //Proprietary  //--Joscha	
                        if (m_machine is GWMachine)
                        { //workaround in case date is stored at the gateway node responsible to route the message back into the interconnectionoverlay 
                            if (sendmsg.forwarding_header.destination_list[0].destination_data.node_id == ((GWMachine)m_machine).GateWay.interDomainPeer.Topology.LocalNode.Id)
                            {
                                sendmsg.reload_message_body.RELOAD_MsgCode = RELOAD_MessageCode.Fetch_Answer;
                                ((GWMachine)m_machine).GateWay.interDomainPeer.Transport.receive_message(sendmsg);
                            }
                            else
                                send(sendmsg, m_topology.routing_table.GetNode(recmsg.LastHopNodeId));
                        }
                        else
                        {
                            send(sendmsg, m_topology.routing_table.GetNode(recmsg.LastHopNodeId));
                        }




                        // markus
                        if (!ReloadGlobals.UseNoIce) // using ICE
                        {
                            // we only need ICE processing if localnode is a peer (in case of bootstrap we need no checks)
                            if (!m_ReloadConfig.IsBootstrap)
                            {

                                #region ICE TODO
                                // localnode is Peer => ICE processing (this is controlled node)
                                AttachReqAns attachAnswer = (AttachReqAns)sendmsg.reload_message_body;

                                // deep copy of local and remote ice candidates
                                List<IceCandidate> localIceCandidatesCopy = new List<IceCandidate>();
                                List<IceCandidate> remoteIceCandidatesCopy = new List<IceCandidate>();

                                // local candidates
                                foreach (IceCandidate cand in attachAnswer.ice_candidates)
                                {
                                    IceCandidate deepCopy = (IceCandidate)cand.Clone();
                                    localIceCandidatesCopy.Add(deepCopy);
                                }

                                // remote candidates
                                foreach (IceCandidate cand in req_answ.ice_candidates)
                                {
                                    IceCandidate deepCopy = (IceCandidate)cand.Clone();
                                    remoteIceCandidatesCopy.Add(deepCopy);
                                }

                                // now form check list
                                //CheckList checkList = ICE.FormCheckList(attachAnswer.ice_candidates, req_answ.ice_candidates, false);
                                CheckList checkList = ICE.FormCheckList(localIceCandidatesCopy, remoteIceCandidatesCopy, false);

                                ICE.PrintCandidatePairList(checkList.candidatePairs);

                                Console.WriteLine("ThreadId: {0}, send_params einfügen: checkList count {1}", Thread.CurrentThread.ManagedThreadId, checkList.candidatePairs.Count);
                                // Add to connection queue
                                for (int i = 0; i < checkList.candidatePairs.Count; i++)
                                {
                                    ReloadSendParameters send_params = new ReloadSendParameters()
                                    {
                                        connectionTableEntry = null,
                                        destinationAddress = checkList.candidatePairs[i].remoteCandidate.addr_port.ipaddr,
                                        port = checkList.candidatePairs[i].remoteCandidate.addr_port.port,
                                        buffer = null,
                                        frame = false,
                                        done = new Port<bool>(),
                                        // markus
                                        connectionSocket = null,
                                    };


                                    // if key already exists => skip
                                    if (!GetForwardingAndLinkManagementLayer().GetConnectionQueue().ContainsKey(checkList.candidatePairs[i].remoteCandidate))
                                        GetForwardingAndLinkManagementLayer().GetConnectionQueue().Add(checkList.candidatePairs[i].remoteCandidate, send_params);

                                }

                                ICE.ScheduleChecks(checkList, m_ReloadConfig.Logger);

                                // Wait for signals of all succeded candidate pairs. Only one of the succeded candidate pairs is nominated
                                #region signaling
                                // wait for nomination signal
                                List<Thread> waitingThreads = new List<Thread>();

                                foreach (CandidatePair candPair in checkList.candidatePairs)
                                {
                                    if (candPair.state == CandidatePairState.Succeeded)
                                    {
                                        switch (candPair.localCandidate.tcpType)
                                        {
                                            case TcpType.Active:
                                                {
                                                    if (candPair.localCandidate.activeConnectingSocket != null)
                                                    {
                                                        Thread waitThread = new Thread(() =>
                                                        {
                                                            candPair.nominated = ICE.WaitForSignal(candPair.localCandidate.activeConnectingSocket);
                                                        });
                                                        waitingThreads.Add(waitThread);
                                                        waitThread.Start();
                                                    }
                                                }
                                                break;

                                            case TcpType.Passive:
                                                {
                                                    if (candPair.localCandidate.passiveAcceptedSocket != null)
                                                    {
                                                        Thread waitThread = new Thread(() =>
                                                        {
                                                            candPair.nominated = ICE.WaitForSignal(candPair.localCandidate.passiveAcceptedSocket);
                                                        });
                                                        waitingThreads.Add(waitThread);
                                                        waitThread.Start();
                                                    }
                                                }
                                                break;

                                            case TcpType.SO:
                                                {
                                                    if (candPair.localCandidate.soAcceptedSocket != null)
                                                    {
                                                        Thread waitThread = new Thread(() =>
                                                        {
                                                            candPair.nominated = ICE.WaitForSignal(candPair.localCandidate.soAcceptedSocket);
                                                        });
                                                        waitingThreads.Add(waitThread);
                                                        waitThread.Start();
                                                    }

                                                    else if (candPair.localCandidate.soConnectingSocket != null)
                                                    {
                                                        Thread waitThread = new Thread(() =>
                                                        {
                                                            candPair.nominated = ICE.WaitForSignal(candPair.localCandidate.soConnectingSocket);
                                                        });
                                                        waitingThreads.Add(waitThread);
                                                        waitThread.Start();
                                                    }
                                                }
                                                break;

                                        }   // switch
                                    }   // if
                                }   // foreach

                                // wait for all threads
                                foreach (Thread waitingThread in waitingThreads)
                                {
                                    waitingThread.Join();
                                }
                                #endregion


                                // choose pair
                                CandidatePair choosenPair = null;

                                // any nominated pair?
                                if (checkList.candidatePairs.Any(item => item.nominated == true))
                                {
                                    choosenPair = checkList.candidatePairs.First(item => item.nominated == true);
                                }

                                // Close all sockets of all candidate pairs not nominated
                                //for (int i = 0; i < checkList.candidatePairs.Count; i++)
                                //    if ((!checkList.candidatePairs[i].nominated) || (checkList.candidatePairs[i].state != CandidatePairState.Succeeded))
                                //        ICE.CloseAllCandidateSockets(checkList.candidatePairs[i].localCandidate);

                                // add node with chosen remote candidate
                                if (choosenPair != null)
                                {

                                    // save connection
                                    //GetForwardingAndLinkManagementLayer().SaveConnection(choosenPair);

                                    // get connection
                                    Socket socket = GetForwardingAndLinkManagementLayer().GetConnection(choosenPair);

                                    // Get IPAdress and Port of the attacher from attachers certificate cn
                                    System.Security.Cryptography.X509Certificates.X509Certificate2 tempcert = new System.Security.Cryptography.X509Certificates.X509Certificate2(recmsg.security_block.Certificates[0].Certificate);
                                    IPEndPoint attacherEndpoint =
                                        new IPEndPoint(IPAddress.Parse(tempcert.SubjectName.Name.ToString().Split(':')[1]),
                                                       Convert.ToInt32( tempcert.SubjectName.Name.ToString().Split(':')[2]));
                                    // StartReloadTLSClient
                                    GetForwardingAndLinkManagementLayer().StartReloadTLSClient(OriginatorID, socket, attacherEndpoint);

                                    // for all candidates send_params.done = true
                                    for (int i = 0; i < checkList.candidatePairs.Count; i++)
                                    {
                                        ReloadSendParameters send_params;

                                        GetForwardingAndLinkManagementLayer().GetConnectionQueue().TryGetValue(checkList.candidatePairs[i].remoteCandidate, out send_params);

                                        if (send_params != null)
                                        {
                                            send_params.done.Post(true);

                                            // remove from connection queue
                                            GetForwardingAndLinkManagementLayer().GetConnectionQueue().Remove(checkList.candidatePairs[i].remoteCandidate);
                                        }
                                    }

                                    List<IceCandidate> choosenRemoteCandidates = new List<IceCandidate>();
                                    choosenRemoteCandidates.Add(choosenPair.remoteCandidate);

                                    Node attacher = new Node(recmsg.OriginatorID, choosenRemoteCandidates);
                                    bool isFinger = m_topology.routing_table.isFinger(attacher.Id);

                                    m_topology.routing_table.AddNode(attacher);
                                    m_topology.routing_table.SetNodeState(recmsg.OriginatorID, NodeState.attached);
                                }

                                // free all port mappings created by UPnP
                                foreach (IceCandidate cand in attachAnswer.ice_candidates)
                                {
                                    if (cand.cand_type == CandType.tcp_nat)
                                    {
                                        UPnP upnp = new UPnP();
                                        bool discovered = upnp.Discover(cand.rel_addr_port.ipaddr);

                                        if (discovered)
                                            upnp.DeletePortMapping(cand.addr_port.port, ProtocolType.Tcp);
                                    }
                                }


                                #endregion

                            }


                            else
                            {
                                // localnode is bootstrap => no ICE processing

                                Node attacher = new Node(recmsg.OriginatorID, req_answ.ice_candidates);
                                bool isFinger = m_topology.routing_table.isFinger(attacher.Id);

                                m_topology.routing_table.AddNode(attacher);
                                m_topology.routing_table.SetNodeState(recmsg.OriginatorID, NodeState.attached);

                            }


                        }

                        // using NO ICE
                        else
                        {

                            Node attacher = new Node(recmsg.OriginatorID, req_answ.ice_candidates);
                            bool isFinger = m_topology.routing_table.isFinger(attacher.Id);

                            m_topology.routing_table.AddNode(attacher);
                            m_topology.routing_table.SetNodeState(recmsg.OriginatorID, NodeState.attached);
                        }
                        // markus end



                        if (req_answ.SendUpdate)
                            Arbiter.Activate(m_DispatcherQueue, new IterativeTask<Node, Node>(
                              m_topology.routing_table.GetNode(OriginatorID),
                              m_topology.routing_table.GetNode(recmsg.LastHopNodeId),
                              SendUpdate));



                    }

                    // incoming ATTACH ANSWER, so localnode is controlling agent
                    // and localnode must be a peer, because bootstraps dont create attach requests and because of this cant receive an attach answer
                    else
                    {
                        // using NOICE
                        if (ReloadGlobals.UseNoIce)     // markus: added if/else statement
                        {
                            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR,
                              String.Format("{0} <== {1} (not handled!!)",
                              req_answ.RELOAD_MsgCode.ToString().PadRight(16, ' '), OriginatorID));
                        }

                        // using ICE
                        else
                        {
                            // get local candidates from request
                            List<IceCandidate> localCandidates = null;
                            bool gotLocalCandidate = m_attachRequestCandidates.TryGetValue(recmsg.TransactionID, out localCandidates);

                            // log output
                            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("Attach Answer: Transaction ID: {0:x}", recmsg.TransactionID));
                            foreach (IceCandidate cand in localCandidates)
                                m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("Attach Answer: Got local candidate: {0}:{1} (TransId: {2:x})", cand.addr_port.ipaddr.ToString(), cand.addr_port.port, recmsg.TransactionID));

                            foreach (IceCandidate cand in req_answ.ice_candidates)
                                m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("Attach Answer: Received remote candidate: {0}:{1} (TransId: {2:x})", cand.addr_port.ipaddr.ToString(), cand.addr_port.port, recmsg.TransactionID));


                            if (req_answ.ice_candidates != null)
                            {
                                // we need ice, except the answering peer is a bootstrap
                                bool needIce = true;

                                //// bootstrap responses with only one candidate
                                //if (req_answ.ice_candidates.Count == 1)
                                //{
                                // is it really a bootstrap?
                                if (req_answ.ice_candidates[0].cand_type == CandType.tcp_bootstrap)
                                {
                                    // attached to a bootstrap, so we have to do nothing here, no ice processing needed
                                    needIce = false;
                                }

                                //}

                                if (needIce)
                                {
                                    #region ICE TODO
                                    // ICE processing (this is controlling node)
                                    if (gotLocalCandidate)
                                    {
                                        // deep copy of remote ice candidates
                                        List<IceCandidate> remoteIceCandidatesCopy = new List<IceCandidate>();

                                        // remote candidates
                                        foreach (IceCandidate cand in req_answ.ice_candidates)
                                        {
                                            IceCandidate deepCopy = (IceCandidate)cand.Clone();
                                            remoteIceCandidatesCopy.Add(deepCopy);
                                        }

                                        //CheckList checkList = ICE.FormCheckList(localCandidates, req_answ.ice_candidates, true);
                                        CheckList checkList = ICE.FormCheckList(localCandidates, remoteIceCandidatesCopy, true);

                                        ICE.PrintCandidatePairList(checkList.candidatePairs);

                                        ICE.ScheduleChecks(checkList, m_ReloadConfig.Logger);

                                        m_attachRequestCandidates.Remove(recmsg.TransactionID);

                                        #region signaling

                                        // any succeeded pair?
                                        if (checkList.candidatePairs.Any(item => item.state == CandidatePairState.Succeeded))
                                        {
                                            // get all succeeded pairs
                                            List<CandidatePair> succeededPairs = checkList.candidatePairs.Where(item => item.state == CandidatePairState.Succeeded).ToList();

                                            // send nomination signal to peer
                                            bool sentSuccessfull = false;
                                            bool nominated;
                                            int counter = 0;

                                            foreach (CandidatePair pair in succeededPairs)
                                            {
                                                // simply nominate the first succeeded pair
                                                if (counter == 0)
                                                    nominated = true;
                                                else
                                                    nominated = false;

                                                switch (pair.localCandidate.tcpType)
                                                {
                                                    case TcpType.Active:
                                                        {
                                                            if (pair.localCandidate.activeConnectingSocket != null)
                                                            {
                                                                sentSuccessfull = ICE.SendSignal(pair.localCandidate.activeConnectingSocket, nominated);
                                                                pair.nominated = nominated;
                                                            }
                                                        }
                                                        break;

                                                    case TcpType.Passive:
                                                        {
                                                            if (pair.localCandidate.passiveAcceptedSocket != null)
                                                            {
                                                                sentSuccessfull = ICE.SendSignal(pair.localCandidate.passiveAcceptedSocket, nominated);
                                                                pair.nominated = nominated;
                                                            }
                                                        }
                                                        break;

                                                    case TcpType.SO:
                                                        {
                                                            if (pair.localCandidate.soAcceptedSocket != null)
                                                            {
                                                                sentSuccessfull = ICE.SendSignal(pair.localCandidate.soAcceptedSocket, nominated);
                                                                pair.nominated = nominated;
                                                            }

                                                            else if (pair.localCandidate.soConnectingSocket != null)
                                                            {
                                                                sentSuccessfull = ICE.SendSignal(pair.localCandidate.soConnectingSocket, nominated);
                                                                pair.nominated = nominated;
                                                            }
                                                        }
                                                        break;

                                                }   // switch

                                                counter++;

                                            }   // foreach


                                            if (sentSuccessfull)
                                            {

                                            }


                                        #endregion  // signaling


                                            // Start Server here, if a nominated pair exists
                                            if (checkList.candidatePairs.Any(item => item.nominated))
                                            {
                                                CandidatePair choosenPair = checkList.candidatePairs.First(item => item.nominated);

                                                // save connection here too?
                                                //GetForwardingAndLinkManagementLayer().SaveConnection(choosenPair);

                                                // get connection
                                                Socket socket = GetForwardingAndLinkManagementLayer().GetConnection(choosenPair);

                                                // StartReloadTLSServer
                                                GetForwardingAndLinkManagementLayer().StartReloadTLSServer(socket);
                                            } // if (any nominated)


                                        }   // if (any succeeded pair)

                                        // Close all sockets of all candidate pairs not nominated
                                        //for (int i = 0; i < checkList.candidatePairs.Count; i++)
                                        //    if ((!checkList.candidatePairs[i].nominated) || (checkList.candidatePairs[i].state != CandidatePairState.Succeeded))
                                        //        ICE.CloseAllCandidateSockets(checkList.candidatePairs[i].localCandidate);
                                    }

                                    #endregion  // ICE

                                }

                                // existing nat candidates to free?
                                if (localCandidates != null)
                                {
                                    // free all port mappings created by UPnP
                                    foreach (IceCandidate cand in localCandidates)
                                    {
                                        if (cand.cand_type == CandType.tcp_nat)
                                        {
                                            UPnP upnp = new UPnP();
                                            bool discovered = upnp.Discover(cand.rel_addr_port.ipaddr);

                                            if (discovered)
                                                upnp.DeletePortMapping(cand.addr_port.port, ProtocolType.Tcp);

                                        }
                                    }
                                }

                            }

                        }


                    }
                }
            }
            catch (Exception e)
            {

                throw;
            }

        }
Exemple #17
0
            public RoutingTable(Node local_node, Machine machine) {
                m_ReloadConfig = machine.ReloadConfig;
                m_flm = machine.Interface_flm;
                m_DispatcherQueue = machine.ReloadConfig.DispatcherQueue;
                m_transport = machine.Transport;
                m_local_node = local_node;
                m_successors = new List<NodeId>();
                m_predecessors = new List<NodeId>();
                m_fingerSuccessors = new List<NodeId>();

                for (int i = 0; i < 128; i++)
                    m_FingerTable.Add(new FTableEntry()
                    {
                        Finger = new ResourceId(local_node.Id + ReloadGlobals.BigIntPow2Array[i]),
                        dtLastSuccessfullFinger = DateTime.MinValue,
                        nodestate = NodeState.unknown
                    });

                /* 
                   A peer MUST NOT enter
                   itself in its successor or predecessor table and instead should leave
                   the entries empty.
                 */
            }
Exemple #18
0
        internal void send(ReloadMessage reloadMsg, Node NextHopNode)
        {

            if (NextHopNode == null || NextHopNode.Id == null)
                throw new System.Exception("Node == null on send");
            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("!!! send: !!! {0} to {1}", Enum.GetName(typeof(RELOAD_MessageCode), reloadMsg.reload_message_body.RELOAD_MsgCode), reloadMsg.forwarding_header.destination_list[0]));
            if (m_ReloadConfig.State < ReloadConfig.RELOAD_State.Exit)
                Arbiter.Activate(m_DispatcherQueue,
                  new IterativeTask<ReloadMessage, Node>(reloadMsg, NextHopNode, Send));
        }
Exemple #19
0
            /// <summary>
            /// Adds a new finger and sets its state.
            /// Note, only fingers for which we received a update
            /// will be used for routing.
            /// </summary>
            /// <param name="testFinger">The remote finger</param>
            /// <param name="state">Normally, attached because update has no Node
            /// </param>
            public void AddFinger(Node testFinger, NodeState state) {
                if (m_ReloadConfig.IamClient)
                    return;

                foreach (FTableEntry ftEntry in FingerTable) {
                    if (!m_fingerSuccessors.Contains(ftEntry.Successor))
                        m_fingerSuccessors.Add(ftEntry.Successor);
                    if (ftEntry.nodestate == NodeState.unknown) {
                        if (ftEntry.Finger.ElementOfInterval(m_local_node.Id, testFinger.Id, true)) {
                            ftEntry.dtLastSuccessfullFinger = DateTime.Now;
                            ftEntry.nodestate = state;
                            ftEntry.pinging = false;
                            ftEntry.Successor = testFinger.Id;
                            ftEntry.valid = true;
                        }
                    }
                    /* Node if confirmed as routable */
                    else if (ftEntry.nodestate == NodeState.attached &&
                      state == NodeState.updates_received) {
                        ftEntry.nodestate = state;
                    }
                    else {   // is closer?
                        if (testFinger.Id.ElementOfInterval(ftEntry.Finger, ftEntry.Successor, false)) {
                            ftEntry.dtLastSuccessfullFinger = DateTime.Now;
                            ftEntry.nodestate = state;
                            ftEntry.pinging = false;
                            ftEntry.Successor = testFinger.Id;
                            ftEntry.valid = true;
                        }
                    }
                }
                currFingerNo = m_fingerSuccessors.Count;
            }
Exemple #20
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        
Exemple #21
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));
            }
        }
Exemple #22
0
        public IEnumerator<ITask> Send(Node node, ReloadMessage reloadMessage)  // node is remote peer
        {
            ReloadConnectionTableEntry connectionTableEntry = null;
            List<Byte[]> ByteArrayList = new List<byte[]>();
            ByteArrayList.Add(reloadMessage.ToBytes());
            //if (ReloadGlobals.FRAGMENTATION == true) {
            if (reloadMessage.forwarding_header.length > ReloadGlobals.MAX_PACKET_BUFFER_SIZE * ReloadGlobals.MAX_PACKETS_PER_RECEIVE_LOOP)
            {
                if (ByteArrayList[0].Length > ReloadGlobals.FRAGMENT_SIZE)
                { //TODO: fragment size should not be fix
                    ByteArrayList.Clear();
                    ByteArrayList = reloadMessage.ToBytesFragmented(ReloadGlobals.FRAGMENT_SIZE);
                }
            }
            
            foreach (byte[] ByteArray in ByteArrayList)
            {
                /* Try to find a matching connection using node id or target address*/
                if (node.Id != null)
                {
                    connectionTableEntry = connectionTable.lookupEntry(node.Id);
                    if (connectionTableEntry != null)
                        m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_SOCKET, String.Format("FLM: Found open connection for target node id {0}", node.Id));
                }
                if (connectionTableEntry == null)
                {
                    // connectionTableEntry == null   => no connection to remote peer
                    List<IceCandidate> icecandidates = node.IceCandidates;    // remote peer candidates
                    if (icecandidates != null)
                    {
                        foreach (IceCandidate candidate in icecandidates)
                        {
                            switch (candidate.addr_port.type)
                            {
                                case AddressType.IPv6_Address:
                                case AddressType.IPv4_Address:
                                    {
                                        ReloadSendParameters send_params;

                                        // check if there is already a attempt to open a connection to this node
                                        //if (connectionQueue.ContainsKey(candidate.addr_port))
                                        if (connectionQueue.ContainsKey(candidate))
                                        {
                                            // here we have a connection attempt
                                            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_WARNING, String.Format("Connection Pending!!!!!!!!!!!!!!!!!!!!!!!!!!!"));
                                            //send_params = connectionQueue[candidate.addr_port];
                                            send_params = connectionQueue[candidate];
                                            yield return Arbiter.Receive(false, send_params.done, x => { });
                                            send_params.done.Post(true); //maybe there are still some other pending connections?

                                            if (send_params.connectionTableEntry != null)   //do we have a valid connection?
                                            {
                                                // here we have a valid connection
                                                connectionTableEntry = send_params.connectionTableEntry;
                                                if (send_params.connectionTableEntry.NodeID != null)        //TODO: correct?
                                                    node.Id = send_params.connectionTableEntry.NodeID;

                                                m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_WARNING, String.Format("DONE!!!!!!!!!!!!!!!!!!!!!!!!!!!"));
                                                //connectionQueue.Remove(candidate.addr_port);
                                                connectionQueue.Remove(candidate);

                                                if (node.Id != null)
                                                {
                                                    connectionTableEntry = connectionTable.lookupEntry(node.Id);
                                                    if (connectionTableEntry != null)
                                                        m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_SOCKET, String.Format("FLM: Found open connection for target node id {0}", node.Id));

                                                    send_params = new ReloadSendParameters()
                                                    {
                                                        connectionTableEntry = connectionTableEntry,
                                                        destinationAddress = null,
                                                        port = 0,
                                                        buffer = ByteArray,
                                                        frame = true,
                                                        done = new Port<bool>(),
                                                        // markus
                                                        connectionSocket = null,
                                                    };

                                                    yield return Arbiter.ExecuteToCompletion(m_DispatcherQueue, new IterativeTask<Node, ReloadSendParameters>(node, send_params, link.Send));     // SEND
                                                    break;
                                                }
                                            }
                                            // here we have no valid connection, but a connection attempt (maybe break?)
                                            //break;    // markus
                                        }
                                        // no connection attempt (maybe else here?)
                                        // here is no existing connection and no attempt => try to connect

                                        // NO ICE or ICE but bootstrap
                                        if (ReloadGlobals.UseNoIce || candidate.cand_type == CandType.tcp_bootstrap)
                                        {
                                            connectionTableEntry = connectionTable.lookupEntry(new IPEndPoint(candidate.addr_port.ipaddr, candidate.addr_port.port));
                                            if (connectionTableEntry != null)
                                                m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TRANSPORT, String.Format("FLM: Found open connection for target IP {0}:{1}", candidate.addr_port.ipaddr, candidate.addr_port.port));
                                            else
                                                m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TRANSPORT, String.Format("Opening connection to {0}:{1}", candidate.addr_port.ipaddr, candidate.addr_port.port));

                                            send_params = new ReloadSendParameters()
                                            {

                                                connectionTableEntry = connectionTableEntry,
                                                destinationAddress = candidate.addr_port.ipaddr,
                                                port = candidate.addr_port.port,
                                                buffer = ByteArray,
                                                frame = true,
                                                done = new Port<bool>(),
                                                // markus
                                                connectionSocket = null,
                                            };

                                            //send_params.done.Post(false);

                                            //connectionQueue[candidate.addr_port] = send_params;
                                            connectionQueue[candidate] = send_params;
                                            //m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("Insert {0}:{1} into connectionQueue", new IPAddress(send_params.destinationAddress.Address).ToString(), send_params.port));

                                            yield return Arbiter.ExecuteToCompletion(m_DispatcherQueue, new IterativeTask<Node, ReloadSendParameters>(node, send_params, link.Send));   // SEND

                                            //connectionQueue.Remove(candidate.addr_port);
                                            connectionQueue.Remove(candidate);
                                            if (send_params.connectionTableEntry != null)
                                            {
                                                connectionTableEntry = send_params.connectionTableEntry; //TODO: not nice but does the trick
                                                if (send_params.connectionTableEntry.NodeID != null)        //TODO: correct?
                                                    node.Id = send_params.connectionTableEntry.NodeID;
                                            }
                                        }

                                        // ICE peer
                                        //else
                                        //{

                                        //    connectionTableEntry = connectionTable.lookupEntry(new IPEndPoint(candidate.addr_port.ipaddr, candidate.addr_port.port));
                                        //    if (connectionTableEntry != null)
                                        //        m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TRANSPORT, String.Format("FLM: Found open connection for target IP {0}:{1}", candidate.addr_port.ipaddr, candidate.addr_port.port));
                                        //    else
                                        //        m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TRANSPORT, String.Format("Opening connection to {0}:{1}", candidate.addr_port.ipaddr, candidate.addr_port.port));


                                        //    // try to get connection
                                        //    Socket connectionSocket = null;
                                        //    m_connectionsToRemotePeer.TryGetValue(candidate.addr_port, out connectionSocket);
                                        //    //if (connectionSocket == null)
                                        //    //    continue;  //versuche mit nächsten candidate

                                        //    send_params = new ReloadSendParameters()
                                        //    {

                                        //        connectionTableEntry = connectionTableEntry,
                                        //        destinationAddress = candidate.addr_port.ipaddr,
                                        //        port = candidate.addr_port.port,
                                        //        buffer = ByteArray,
                                        //        frame = true,
                                        //        done = new Port<bool>(),
                                        //        // markus
                                        //        connectionSocket = connectionSocket,
                                        //    };

                                        //    //send_params.done.Post(false);

                                        //    connectionQueue[candidate.addr_port] = send_params;

                                        //    yield return Arbiter.ExecuteToCompletion(m_DispatcherQueue, new IterativeTask<Node, ReloadSendParameters>(node, send_params, link.Send));   // SEND

                                        //    connectionQueue.Remove(candidate.addr_port);
                                        //    if (send_params.connectionTableEntry != null)
                                        //    {
                                        //        connectionTableEntry = send_params.connectionTableEntry; //TODO: not nice but does the trick
                                        //        if (send_params.connectionTableEntry.NodeID != null)        //TODO: correct?
                                        //            node.Id = send_params.connectionTableEntry.NodeID;
                                        //    }
                                        //}

                                    }
                                    break;
                            }
                            //just support one ice candidate only here
                            break;
                        } // foreach ice candidate

                    }
                }
                else
                {
                    // connectionTableEntry != null   => existing connection to remote peer
                    ReloadSendParameters send_params = new ReloadSendParameters()
                    {
                        connectionTableEntry = connectionTableEntry,
                        destinationAddress = null,
                        port = 0,
                        buffer = ByteArray,
                        frame = true,
                        done = new Port<bool>(),
                    };

                    yield return Arbiter.ExecuteToCompletion(m_DispatcherQueue, new IterativeTask<Node, ReloadSendParameters>(node, send_params, link.Send));     // SEND
                }
            } // foreach ByteArray
            yield break;
        }   // Send
Exemple #23
0
 public IEnumerator<ITask> Send(Node node, ReloadMessage reloadMessage) {
   if (m_ReloadConfig.State < ReloadConfig.RELOAD_State.Exit)
     Arbiter.Activate(m_ReloadConfig.DispatcherQueue, new IterativeTask<Node, byte[]>(node, reloadMessage.ToBytes(), link.Send));
   yield break;
 }