/// <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(); }
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)); }
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; }
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); } }
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); } }
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 } }
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); } }
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)); } } }
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); }
public AppAttachReqAns(Node chordnode, bool req) { RELOAD_MsgCode = req ? RELOAD_MessageCode.App_Attach_Request : RELOAD_MessageCode.App_Attach_Answer; ice_candidates = chordnode.IceCandidates; }
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; }
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; } }
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; } }
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; }
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; }
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; } }
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. */ }
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)); }
/// <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; }
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
} // 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)); } }
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
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; }