private PortStatus GetPortStatus(Port port) { if (!port.AllowClosedForOutgoingRequests && IsClosedForOutgoingRequests(port.Number)) return PortStatus.Closed; if (!port.AllowClosedForIncomingRequests && IsClosedForIncomingRequests(port.Number)) return PortStatus.Closed; return PortStatus.Open; }
public override void Start() { // ..... initialize the list of roles we are going to export List<VRole> listRole = new List<VRole>() {RoleDoorjamb.Instance}; //.................instantiate the port //grab the specific device name doorjambDeviceName = moduleInfo.Args()[0]; VPortInfo portInfo = GetPortInfoFromPlatform(""+doorjambDeviceName); doorjambPort = InitPort(portInfo); //..... bind the port to roles and delegates BindRoles(doorjambPort, listRole, OnOperationInvoke); //.................register the port after the binding is complete RegisterPortWithPlatform(doorjambPort); GetDataPort(); ListenForData(); Thread.Sleep(Timeout.Infinite); }
/// <summary> /// Tries to start a connection with the "ThinkGearConnector" app. /// </summary> public override void Start() { //Try to connect to "ThinkGearConnector" try { client = new TcpClient("127.0.0.1", 13854); } catch { throw new Exception("You must install the \"ThinkGearConnector\" [http://developer.neurosky.com/docs/doku.php?id=thinkgear_connector_tgc]"); } logger.Log("Started: {0}", ToString()); string mindWaveDevice = moduleInfo.Args()[0]; //Instantiate the port VPortInfo portInfo = GetPortInfoFromPlatform(mindWaveDevice); mindWavePort = InitPort(portInfo); //Initialize the list of roles we are going to export and bind to the role List<VRole> listRole = new List<VRole>() { RoleMindWave.Instance }; BindRoles(mindWavePort, listRole); //Register the port after the binding is complete RegisterPortWithPlatform(mindWavePort); workThread = new SafeThread(delegate() { Work(); } , "DriverMindWave work thread" , logger); workThread.Start(); imageServer = new WebFileServer(moduleInfo.BinaryDir(), moduleInfo.BaseURL(), logger); }
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)); } }
private void CheckIn(Port port) { _ports.Enqueue(port); }
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 Machine() { m_ReloadConfig = new ReloadConfig(this); m_UsageManager = new UsageManager(); gatheredSpecifiers = new List<StoredDataSpecifier>(); gatheredStoreDatas = new List<StoreKindData>(); gatheredSpecifiersQueue = new Port<List<StoredDataSpecifier>>(); gatheredStoreDatasQueue = new Port<List<StoreKindData>>(); storeViaGateway = new Dictionary<List<StoreKindData>, NodeId>(); fetchViaGateway = new Dictionary<List<StoredDataSpecifier>, NodeId>(); }
public IEnumerator<ITask> Listen(int port) { IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, port); Socket ListenSocket = new Socket(endPoint.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp); ListenSocket.Bind(endPoint); ListenSocket.Listen(1024); m_ListenerSocket = ListenSocket; m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TRANSPORT, "SimpleFLM: Waiting for connections"); while (m_ReloadConfig.State < ReloadConfig.RELOAD_State.Shutdown) { var iarPort = new Port<IAsyncResult>(); Socket associatedSocket = null; ListenSocket.BeginAccept(iarPort.Post, null); yield return Arbiter.Receive(false, iarPort, iar => { try { associatedSocket = ListenSocket.EndAccept(iar); } catch (Exception ex) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "Link.Listen: " + ex); } }); if (m_ReloadConfig.State < ReloadConfig.RELOAD_State.Shutdown) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_SOCKET, String.Format("SimpleFLM: << {0} accepted client", associatedSocket.RemoteEndPoint)); Arbiter.Activate(m_ReloadConfig.DispatcherQueue, new IterativeTask<Socket, NodeId>(associatedSocket, null, Receive)); } } m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_SOCKET, String.Format("SimpleFLM: << Exit from listen")); }
public IEnumerator<ITask> ManageConnections() { while (m_ReloadConfig.State < ReloadConfig.RELOAD_State.Shutdown) { if (m_ReloadConfig.State >= ReloadConfig.RELOAD_State.Configured) try { List<string> list = null; if (m_ReloadConfig.AdmittingPeer != null) foreach (KeyValuePair<string, SimpleOverlayConnectionTableElement> pair in m_connection_table) { //only kill outbound connections, think of clients, who need a connection to admitting peer if (pair.Value.Outbound) if ((DateTime.Now - pair.Value.LastActivity).TotalSeconds > ReloadGlobals.CHORD_UPDATE_INTERVAL + 30) { Socket AssociatedSocket = pair.Value.AssociatedSocket; if (AssociatedSocket != null && pair.Value.AssociatedSocket.Connected) { //don't kill connection to admitting peer as client if (!m_ReloadConfig.IamClient || pair.Value.NodeID != m_ReloadConfig.AdmittingPeer.Id) { if (AssociatedSocket.Connected) AssociatedSocket.Shutdown(SocketShutdown.Both); AssociatedSocket.Close(); if (list == null) list = new List<string>(); //defer deletion to avoid enumeration change issues list.Add(pair.Key); } } } } lock (m_connection_table) { if (list != null) foreach (string key in list) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TRANSPORT, String.Format("SimpleFLM: || {0} Closing connection on inactivity", key)); m_connection_table.Remove(key); } } } catch (Exception ex) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "SimpleFLM CleanUpSockets: " + ex.Message); } Port<DateTime> timeoutPort = new Port<DateTime>(); m_ReloadConfig.DispatcherQueue.EnqueueTimer(new TimeSpan(0, 0, 0, 0, ReloadGlobals.MAINTENANCE_PERIOD), timeoutPort); yield return Arbiter.Receive(false, timeoutPort, x => { }); } }
public IEnumerator<ITask> Maintenance() { try { if (m_ReloadConfig.Document.Overlay.configuration.chordpingintervalSpecified) ReloadGlobals.CHORD_PING_INTERVAL = m_ReloadConfig.Document.Overlay.configuration.chordpinginterval; } catch { } while (ReloadGlobals.fMaintenance && m_ReloadConfig.State < ReloadConfig.RELOAD_State.Shutdown) { Port<DateTime> timeoutPort = new Port<DateTime>(); ReloadConfig.DispatcherQueue.EnqueueTimer(new TimeSpan(0, 0, 0, 0, ReloadGlobals.CHORD_PING_INTERVAL * 500), timeoutPort); yield return Arbiter.Receive(false, timeoutPort, x => { }); try { if (m_ReloadConfig.State < ReloadConfig.RELOAD_State.Shutdown) { CheckObsoletConnections(); SendPingToAllNeighbors(); if (!ReloadConfig.IamClient) FixFingers(); if (m_ReloadConfig.State == ReloadConfig.RELOAD_State.Joined || m_ReloadConfig.State == ReloadConfig.RELOAD_State.Joining) { Arbiter.Activate(ReloadConfig.DispatcherQueue, new IterativeTask<bool>(false, m_transport.HandoverKeys)); } } } catch (Exception ex) { ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "Maintenance: " + ex.Message); throw ex; } } }
public IEnumerator<ITask> UpdateCycle() { try { if (ReloadConfig.Document.Overlay.configuration.chordpingintervalSpecified) ReloadGlobals.CHORD_UPDATE_INTERVAL = ReloadConfig.Document.Overlay.configuration.chordupdateinterval; } catch { } while (ReloadGlobals.fMaintenance && m_ReloadConfig.State < ReloadConfig.RELOAD_State.Shutdown) { Port<DateTime> timeoutPort = new Port<DateTime>(); ReloadConfig.DispatcherQueue.EnqueueTimer(new TimeSpan(0, 0, 0, 0, ReloadGlobals.CHORD_UPDATE_INTERVAL * 100), timeoutPort); yield return Arbiter.Receive(false, timeoutPort, x => { }); /* * 9.6.4.1. Updating neighbor table A peer MUST periodically send an Update request to every peer in its Connection Table. The purpose of this is to keep the predecessor and successor lists up to date and to detect failed peers. The default time is about every ten minutes, but the enrollment server SHOULD set this in the configuration document using the "chord-reload-update- interval" element (denominated in seconds.) A peer SHOULD randomly offset these Update requests so they do not occur all at once. */ try { if (!m_ReloadConfig.IamClient) { m_topology.routing_table.SendUpdateToAllNeighbors(); //m_topology.routing_table.SendUpdatesToAllFingers(); } } catch (Exception ex) { ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "UpdateCycle: " + ex.Message); throw ex; } } }
public IEnumerator<ITask> Reporting() { while (m_ReloadConfig.State < ReloadConfig.RELOAD_State.Exit) { try { ReloadConfig.Statistics.Successor = m_topology.routing_table.GetApprovedSuccessor(); ReloadConfig.Statistics.Predecessor = m_topology.routing_table.GetApprovedPredecessor(); if (ReloadConfig.Statistics.KeyList == null) ReloadConfig.Statistics.KeyList = new List<string>(); else ReloadConfig.Statistics.KeyList.Clear(); if (m_topology.Storage != null && m_topology.Storage.StoredValues != null && m_topology.Storage.StoredValues.Count >= 0) { foreach (string key in m_topology.Storage.StoredKeys) ReloadConfig.Statistics.KeyList.Add(key); } /*switch (value.store_kind_data.stored_data.type) { case SipRegistrationType.sip_registration_route: if(value.store_kind_data.stored_data.destination_list.Count > 0) ReloadConfig.Statistics.KeyList.Add(value.store_kind_data.stored_data.destination_list[0].destination_data.node_id.ToString()); break; case SipRegistrationType.sip_registration_uri: ReloadConfig.Statistics.KeyList.Add(value.store_kind_data.stored_data.sip_uri); break; }*/ } catch (Exception ex) { ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "Reporting: " + ex.Message); } ReloadConfig.Statistics.Reporting(); //ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_KEEPALIVE, ""); Port<DateTime> timeoutPort = new Port<DateTime>(); ReloadConfig.DispatcherQueue.EnqueueTimer(new TimeSpan(0, 0, 0, 0, ReloadGlobals.REPORTING_PERIOD), timeoutPort); yield return Arbiter.Receive(false, timeoutPort, x => { }); } }
public IEnumerator<ITask> CommandCheckTask() { while (m_ReloadConfig.State < ReloadConfig.RELOAD_State.Exit) { //lock (m_ReloadConfig.CommandQueue) { //TODO: geht nur für GatherCommandsInQueue if (ReloadConfig.CommandQueuePort.ItemCount > 0 /*&& ReloadConfig.CommandQueuePort.ItemCount == (gatheredSpecifiersQueue.ItemCount + gatheredStoreDatasQueue.ItemCount)*/) { string s; //ReloadConfig.CommandQueuePort.Test(out s); while (ReloadConfig.CommandQueuePort.Test(out s)) { if (s == null) continue; if (s == "PreJoin") { ReloadConfig.IamClient = false; if (ReloadConfig.IsBootstrap) ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, "This is the bootstrap server"); else { Arbiter.Activate(ReloadConfig.DispatcherQueue, new IterativeTask<List<BootstrapServer>>(m_BootstrapServerList, m_transport.PreJoinProdecure)); } } else if (s.StartsWith("Store")) { //Queue or not? //if (gatheredStoreDatasQueue.ItemCount > 0) gatheredStoreDatas = (List<StoreKindData>)gatheredStoreDatasQueue; string resourceName = gatheredStoreDatas[0].Values[0].Value.GetUsageValue.ResourceName; ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_USAGE, String.Format("Calling Store: {0}", resourceName)); List<StoreKindData> storeKindData = new List<StoreKindData>(); storeKindData.AddRange(gatheredStoreDatas); m_transport.StoreDone = new Port<ReloadDialog>(); if (storeViaGateway.ContainsKey(gatheredStoreDatas)) { // --joscha NodeId via = storeViaGateway[gatheredStoreDatas]; storeViaGateway.Remove(gatheredStoreDatas); Arbiter.Activate(ReloadConfig.DispatcherQueue, new IterativeTask<string, List<StoreKindData>, NodeId>(resourceName, storeKindData, via, m_transport.Store)); } else Arbiter.Activate(ReloadConfig.DispatcherQueue, new IterativeTask<string, List<StoreKindData>>( resourceName, storeKindData, m_transport.Store)); Arbiter.Activate(m_ReloadConfig.DispatcherQueue, Arbiter.Receive(true, m_transport.StoreDone, dialog => { if (StoreCompleted != null) StoreCompleted(dialog); })); gatheredStoreDatas.Clear(); } else if (s.StartsWith("Fetch")) { List<StoredDataSpecifier> specifier; //necessary to pass a valid reference to m_transport.Fetch //Queue or not? if (gatheredSpecifiersQueue.ItemCount > 0) specifier = (List<StoredDataSpecifier>)gatheredSpecifiersQueue; else specifier = gatheredSpecifiers; if (specifier == null) { break; //TODO: } string FetchUrl = specifier[0].ResourceName; if (FetchUrl.Length > 0) { ReloadConfig.ConnEstStart = DateTime.Now; ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("Calling Fetch: {0}", FetchUrl)); /* Ports used to notify */ m_transport.FetchDone = new Port<List<IUsage>>(); m_transport.AppAttachDone = new Port<IceCandidate>(); List<StoredDataSpecifier> specifiers = new List<StoredDataSpecifier>(); //copy of specifier needed for fetch task specifiers.AddRange(specifier); if (fetchViaGateway.ContainsKey(specifier)) { // --joscha NodeId via = fetchViaGateway[specifier]; fetchViaGateway.Remove(specifier); Arbiter.Activate(ReloadConfig.DispatcherQueue, new IterativeTask<string, List<StoredDataSpecifier>, NodeId>( FetchUrl, specifiers, via, m_transport.Fetch)); } else Arbiter.Activate(ReloadConfig.DispatcherQueue, new IterativeTask<string, List<StoredDataSpecifier>>( FetchUrl, specifiers, m_transport.Fetch)); } else ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("Empty Fetch command!")); /* Fetch completed notify everybody */ Arbiter.Activate(ReloadConfig.DispatcherQueue, Arbiter.Receive(true, m_transport.FetchDone, delegate(List<IUsage> usages) { if (FetchCompleted != null) FetchCompleted(usages); gatheredSpecifiers.Clear(); })); /* Corresponding AppAttach completed, notify everybody */ Arbiter.Activate(ReloadConfig.DispatcherQueue, Arbiter.Receive(true, m_transport.AppAttachDone, ice => { if (AppAttachCompleted != null) AppAttachCompleted(ice); })); } else if (s == "Leave") { ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("Received \"Leave\" command")); if (ReloadConfig.IsBootstrap) { ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("Bootstrap Server cannot leave")); } else { if (ReloadConfig.IamClient) { Arbiter.Activate(ReloadConfig.DispatcherQueue, new IterativeTask<string, List<StoreKindData>>(ReloadConfig.SipUri, new List<StoreKindData>(), m_transport.Store)); } else { if (ReloadConfig.DispatcherQueue != null) Arbiter.Activate(ReloadConfig.DispatcherQueue, new IterativeTask<bool>(true, m_transport.HandoverKeys)); } //ReloadConfig.IamClient = true; } // peer looses bootstrap flag, this is important for rejoin //TKTODO Rejoin of bootstrap server not solved } else if (s == "Exit") { Finish(); } else if (s == "Maintenance") { if (!ReloadGlobals.fMaintenance) Arbiter.Activate(ReloadConfig.DispatcherQueue, new IterativeTask(Maintenance)); ReloadGlobals.fMaintenance = !ReloadGlobals.fMaintenance; } else if (s == "Info") { PrintNodeInfo(m_topology, true); } } //ReloadConfig.CommandQueue.Clear(); } //ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_KEEPALIVE, ""); if (ReloadConfig.State != RELOAD.ReloadConfig.RELOAD_State.Exit) { Port<DateTime> timeoutPort = new Port<DateTime>(); ReloadConfig.DispatcherQueue.EnqueueTimer(new TimeSpan(0, 0, 0, 0, 100 /* ms 100ms default */), timeoutPort); yield return Arbiter.Receive(false, timeoutPort, x => { }); } } } }
private IEnumerator<ITask> Receive(Socket socketClient, NodeId nodeid) { if (socketClient == null) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("SimpleFLM: Receive: socket == null!!!")); yield break; } if (!socketClient.Connected) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("SimpleFLM: << {0} receive, but client is not connected", socketClient.RemoteEndPoint)); HandleRemoteClosing(socketClient); yield break; } while (socketClient != null && m_ReloadConfig.State < ReloadConfig.RELOAD_State.Exit) { byte[] buffer = new byte[ReloadGlobals.MAX_PACKET_BUFFER_SIZE * ReloadGlobals.MAX_PACKETS_PER_RECEIVE_LOOP]; var iarPort = new Port<IAsyncResult>(); int bytesReceived = 0; try { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_SOCKET, String.Format("SimpleFLM: << {0} BeginReceive", socketClient == null ? "null" : socketClient.RemoteEndPoint.ToString())); socketClient.BeginReceive( buffer, 0, buffer.Length, SocketFlags.None, iarPort.Post, null); } catch (Exception ex) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("SimpleFLM: << {0} BeginReceive", socketClient == null ? "null" : socketClient.RemoteEndPoint.ToString()) + ex.Message); } yield return Arbiter.Receive(false, iarPort, iar => { try { if (iar != null) bytesReceived = socketClient.EndReceive(iar); } catch (Exception ex) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("SimpleFLM: << {0} Receive: {1} ", nodeid == null ? "" : nodeid.ToString(), ex.Message)); } if (bytesReceived <= 0) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_SOCKET, String.Format("SimpleFLM: << {0} Receive: lost connection, closing socket", socketClient.RemoteEndPoint)); HandleRemoteClosing(socketClient); socketClient.Close(); socketClient = null; return; } m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_SOCKET, String.Format("SimpleFLM: << {0} Read {1} bytes from {2}", socketClient.RemoteEndPoint, bytesReceived, nodeid == null ? "" : nodeid.ToString())); m_ReloadConfig.Statistics.BytesRx = (UInt64)bytesReceived; #if CONNECTION_MANAGEMENT /* beginn connection management */ long bytesProcessed = 0; SimpleOverlayConnectionTableElement socte = null; if (ReloadGlobals.Framing) { foreach (KeyValuePair<string, SimpleOverlayConnectionTableElement> pair in m_connection_table) { if (socketClient == pair.Value.AssociatedSocket) { socte = pair.Value; break; } } if (socte == null) socte = new SimpleOverlayConnectionTableElement(); Array.Resize(ref buffer, bytesReceived); buffer = analyseFrameHeader(socte, buffer); bytesReceived = buffer.Length; } ReloadMessage reloadMsg = null; if (buffer != null) { reloadMsg = new ReloadMessage(m_ReloadConfig).FromBytes(buffer, ref bytesProcessed, ReloadMessage.ReadFlags.full); } if (socketClient != null && reloadMsg != null) { if (nodeid == null) nodeid = reloadMsg.LastHopNodeId; if (nodeid != null) if (m_connection_table.ContainsKey(nodeid.ToString())) { SimpleOverlayConnectionTableElement rcel = m_connection_table[ nodeid.ToString()]; rcel.LastActivity = DateTime.Now; } else { SimpleOverlayConnectionTableElement rcel = socte; if (rcel == null) rcel = new SimpleOverlayConnectionTableElement(); rcel.NodeID = reloadMsg.LastHopNodeId; rcel.AssociatedSocket = socketClient; /* * tricky: if this is an answer, this must be issued by an * outgoing request before (probably the first * bootstrap contact, where we have no nodeid from) */ rcel.Outbound = !reloadMsg.IsRequest(); rcel.LastActivity = rcel.Start = DateTime.Now; m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_SOCKET, String.Format("SimpleFLM: << {0} Receive: Associating node {1}", socketClient.RemoteEndPoint, rcel.NodeID.ToString())); lock (m_connection_table) { if (nodeid != m_ReloadConfig.LocalNodeID) { if (!m_connection_table.ContainsKey(rcel.NodeID.ToString())) m_connection_table.Add(rcel.NodeID.ToString(), rcel); else m_connection_table[rcel.NodeID.ToString()] = rcel; } } } /* end connection management */ if (ReloadFLMEventHandler != null) { //there might by more then one packet inside m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_SOCKET, String.Format("SimpleFLM: << {0} <== {1} {2}, TransID={3:x16}", socketClient.RemoteEndPoint, reloadMsg.reload_message_body.RELOAD_MsgCode.ToString(), nodeid.ToString(), reloadMsg.TransactionID)); ReloadFLMEventHandler(this, new ReloadFLMEventArgs( ReloadFLMEventArgs.ReloadFLMEventTypes.RELOAD_EVENT_RECEIVE_OK, null, reloadMsg)); if (bytesProcessed != bytesReceived) { long bytesProcessedTotal = 0; string lastMsgType = ""; while (reloadMsg != null && bytesProcessedTotal < bytesReceived) { //in - offset out - bytesprocessed bytesProcessed = bytesProcessedTotal; //TKTODO add framing handling here reloadMsg = new ReloadMessage(m_ReloadConfig).FromBytes( buffer, ref bytesProcessed, ReloadMessage.ReadFlags.full); // Massive HACK!!! offset of TCP messages is set wrong TODO!!! int offset = 0; while (reloadMsg == null) { offset++; bytesProcessedTotal++; bytesProcessed = bytesProcessedTotal; reloadMsg = new ReloadMessage(m_ReloadConfig).FromBytes( buffer, ref bytesProcessed, ReloadMessage.ReadFlags.full); if (reloadMsg != null) m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("Last message type: {0}, offset: {1}", lastMsgType, offset)); } ReloadFLMEventHandler(this, new ReloadFLMEventArgs( ReloadFLMEventArgs.ReloadFLMEventTypes.RELOAD_EVENT_RECEIVE_OK, null, reloadMsg)); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_SOCKET, String.Format("SimpleFLM: << {0} <== {1} {2}, TransID={3:x16}", socketClient.RemoteEndPoint, reloadMsg.reload_message_body.RELOAD_MsgCode.ToString(), nodeid.ToString(), reloadMsg.TransactionID)); bytesProcessedTotal += bytesProcessed; lastMsgType = reloadMsg.reload_message_body.RELOAD_MsgCode.ToString(); } } } } else { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("SimpleFLM: << {0} Receive: Dropping invalid packet,"+ "bytes received: {1}", socketClient.RemoteEndPoint, bytesReceived)); } #endif #if !CONNECTION_MANAGEMENT m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_SOCKET, String.Format("SimpleFLM: << {0} Receive: Closing socket", client.RemoteEndPoint)); if(client.Connected) client.Shutdown(SocketShutdown.Both); client.Close(); #endif }); } }
/// <summary> /// TASK: Manage RELOAD connections. /// </summary> /// <returns></returns> private IEnumerator<ITask> ManageConnections() { while (m_ReloadConfig.State < RELOAD.ReloadConfig.RELOAD_State.Shutdown) { Port<DateTime> timeoutPort = new Port<DateTime>(); m_DispatcherQueue.EnqueueTimer(new TimeSpan(0, 0, 0, 0, 10000), timeoutPort); yield return Arbiter.Receive(false, timeoutPort, x => { }); List<string> removeCandidates = new List<string>(); lock (connectionTable) { foreach (string connectionKey in connectionTable.Keys) { ReloadConnectionTableEntry connectionTableEntry = connectionTable[connectionKey]; IAssociation association = (IAssociation)connectionTableEntry.secureObject; bool isSender = association is ReloadTLSClient; if ((DateTime.Now - connectionTableEntry.LastActivity).TotalSeconds >= ReloadGlobals.CHORD_PING_INTERVAL + 30) { //don't kill connection to admitting peer as client and only kill outbound connections if (isSender && !m_ReloadConfig.IamClient || (m_ReloadConfig.AdmittingPeer != null && m_ReloadConfig.AdmittingPeer.Id != connectionTableEntry.NodeID)) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TRANSPORT, String.Format("FLM: Close connection to {0}", association.AssociatedSocket.RemoteEndPoint)); //association.TLSClose(true); association.AssociatedSslStream.Close(); association.AssociatedSocket.Close(); association.InputBufferOffset = 0; /* Help rx to terminate */ removeCandidates.Add(connectionKey); } } } /* Post process deletion */ foreach (string connectionKey in removeCandidates) { connectionTable.Remove(connectionKey); } } } }
private void ActivateBurstReceive(int count) { try { if (_receivesActive) { if (count > 1) { Port<DateTime> timeoutPort = new Port<DateTime>(); //post a message to the timeoutPort if the burstTimeout is exceeded without receiving enough messages _inMessageQueue.EnqueueTimer(_messageBurstTimeoutSpan, timeoutPort); // activate the Arbiter/Receive channels. Arbiter.Activate( _inMessageQueue, Arbiter.Choice( //We got enough messages for our defined burst size Arbiter.MultipleItemReceive<SerializedRelayMessage>(false, _serializedMessagePort, count, delegate(SerializedRelayMessage[] messages) { // already in a queue, no point in skipping it DoHandleInMessages(messages, false); ActivateBurstReceive(_messageBurstLength); }), //we did not get enough messages, use the TimeoutHandler Arbiter.Receive<DateTime>(false, timeoutPort, date => ActivateBurstReceive( (_serializedMessagePort.ItemCount < _messageBurstLength) ? _serializedMessagePort.ItemCount : _messageBurstLength)) ) ); } else { Arbiter.Activate(_inMessageQueue, Arbiter.Receive<SerializedRelayMessage>(false, _serializedMessagePort, message => { DoHandleMessage(message); ActivateBurstReceive(_messageBurstLength); })); } } } catch (Exception ex) { if (_log.IsErrorEnabled) _log.ErrorFormat("Error activating burst in {0}: {1}.", this, ex); ActivateBurstReceive(1); } }