/// <summary> /// Used to populate the chain based on a list of types /// </summary> /// <param name="gateway"></param> /// <param name="side"> </param> /// <param name="workersNeeded"></param> /// <param name="client"></param> /// <param name="server"></param> /// <returns></returns> static WorkerChain PopulateChain(Gateway gateway, ChainSide side, IEnumerable<Type> workersNeeded, IPEndPoint client, IPEndPoint server) { WorkerChain chain = new WorkerChain { ClientEndPoint = client, ServerEndPoint = server, Gateway = gateway, Side = side }; foreach (Type t in workersNeeded) { // ReSharper disable PossibleNullReferenceException Worker w = (Worker)t.GetConstructor(new Type[] { }).Invoke(new object[] { }); // ReSharper restore PossibleNullReferenceException w.Chain = chain; w.ClientEndPoint = client; w.ServerEndPoint = server; chain.Add(w); } /*lock (lockChainManagement) { knownChains.Add(chain); }*/ knownChains.Add(chain); return chain; }
public DebugPortWorker(WorkerChain chain, IPEndPoint client, IPEndPoint server) { Chain = chain; socket = ((TcpReceiver)Chain[0]).Socket; base.ClientEndPoint = client; base.ServerEndPoint = server; sendStream = new BufferedStream(new NetworkStream(socket)); try { lock (sendStream) { Send((int)DebugDataType.GW_NAME); Send(Chain.Gateway.Configuration.GatewayName); Send((int)DebugDataType.FULL_IOC); Send(Chain.Gateway.KnownIocs.Count); foreach (var i in Chain.Gateway.KnownIocs) { Send(i.Key); Send(i.Value.Count); foreach (var j in i.Value) { Send(j); } } Send((int)DebugDataType.FULL_CLIENT); Send(Chain.Gateway.KnownClients.Count); foreach (var i in Chain.Gateway.KnownClients) { Send(i.Key); Send(i.Value.Count); foreach (var j in i.Value) { Send(j); } } if (PBCaGw.Services.DebugTraceListener.TraceAll) Send((int)DebugDataType.FULL_LOGS); else Send((int)DebugDataType.CRITICAL_LOGS); Flush(); PBCaGw.Services.LogEntry[] logs = PBCaGw.Services.DebugTraceListener.LastEntries; foreach (var i in logs) { Send((int)DebugDataType.LOG); Send(i.Source); Send((int)i.EventType); Send(i.Id); Send(i.Message); Flush(); } } } catch { Chain.Dispose(); } Chain.Gateway.NewIocChannel += new NewIocChannelDelegate(GatewayNewIocChannel); Chain.Gateway.DropIoc += new DropIocDelegate(GatewayDropIoc); Chain.Gateway.NewClientChannel += new NewClientChannelDelegate(GatewayNewClientChannel); Chain.Gateway.DropClient += new DropClientDelegate(GatewayDropClient); PBCaGw.Services.DebugTraceListener.LogEntry += GatewayLogEntry; PBCaGw.Services.DebugTraceListener.TraceLevelChanged += new System.EventHandler(DebugTraceListenerTraceLevelChanged); }
/// <summary> /// Link 2 chains together (a client which is connected to an IOC) /// </summary> /// <param name="chain"></param> public void UseChain(WorkerChain chain) { if (chain == null) return; chain.lastNonUsed = null; if (!chain.usedBy.ContainsKey(this)) chain.usedBy.TryAdd(this, this); }
internal void StartGateway() { Configuration.Security.Init(); if (Log.WillDisplay(System.Diagnostics.TraceEventType.Start)) Log.TraceEvent(TraceEventType.Start, -1, "Starting gateway chains"); udpChainA = WorkerChain.UdpChain(this, ChainSide.SIDE_A, configuration.LocalSideA, configuration.RemoteSideB); tcpListenerA = new GwTcpListener(this, ChainSide.SIDE_A, configuration.LocalSideA); beaconA = new BeaconSender(configuration.UdpReceiverA, configuration.LocalSideA, configuration.RemoteSideA); if (configuration.ConfigurationType == ConfigurationType.BIDIRECTIONAL) { udpChainB = WorkerChain.UdpChain(this, ChainSide.SIDE_B, configuration.LocalSideB, configuration.RemoteSideA); tcpListenerB = new GwTcpListener(this, ChainSide.SIDE_B, configuration.LocalSideB); beaconB = new BeaconSender(configuration.UdpReceiverB, configuration.LocalSideB, configuration.RemoteSideB); } else { udpResponseChainA = WorkerChain.UdpResponseChain(this, ChainSide.UDP_RESP_SIDE_A, configuration.LocalSideB, configuration.RemoteSideA); } if (Log.WillDisplay(System.Diagnostics.TraceEventType.Start)) Log.TraceEvent(TraceEventType.Start, -1, "Gateway is ready"); // Recover channels created on a previous session of the gateway if (File.Exists("knownChannels.txt") && RestoreCache) { string[] channelsToRecover; lock (lockChannelList) channelsToRecover = File.ReadAllLines("knownChannels.txt"); foreach (var channelName in channelsToRecover) { DataPacket searchPacket = DataPacket.Create(16 + channelName.Length + DataPacket.Padding(channelName.Length)); searchPacket.PayloadSize = (ushort)(channelName.Length + DataPacket.Padding(channelName.Length)); searchPacket.Kind = DataPacketKind.COMPLETE; searchPacket.DataType = 0; searchPacket.DataCount = Gateway.CA_PROTO_VERSION; searchPacket.Command = 6; searchPacket.Parameter1 = 0; // Version searchPacket.Parameter2 = 0; searchPacket.Sender = udpChainA.ClientEndPoint; searchPacket.SetDataAsString(channelName); udpChainA[2].ProcessData(searchPacket); if (configuration.ConfigurationType == ConfigurationType.BIDIRECTIONAL) { searchPacket = DataPacket.Create(16 + channelName.Length + DataPacket.Padding(channelName.Length)); searchPacket.PayloadSize = (ushort)(channelName.Length + DataPacket.Padding(channelName.Length)); searchPacket.Kind = DataPacketKind.COMPLETE; searchPacket.DataType = 0; searchPacket.DataCount = Gateway.CA_PROTO_VERSION; searchPacket.Command = 6; searchPacket.Parameter1 = 0; // Version searchPacket.Parameter2 = 0; searchPacket.Sender = udpChainB.ClientEndPoint; searchPacket.SetDataAsString(channelName); udpChainB[2].ProcessData(searchPacket); } } } TenSecJobs += new EventHandler(StoreKnownChannels); }
/// <summary> /// Called by the TCP Listener when receiving a new connection. /// Stores a client (request) chain. /// </summary> /// <param name="iPEndPoint"></param> /// <param name="chain"></param> internal static void RegisterClient(IPEndPoint iPEndPoint, WorkerChain chain) { lock (clientConnections) { clientConnections.Add(iPEndPoint, ((TcpReceiver)chain[0]).Socket); clientChains.Add(iPEndPoint, chain); } }
/// <summary> /// Removes an IOC (response) chain /// </summary> /// <param name="chain"></param> internal static void DropServerConnection(WorkerChain chain) { if (chain == null || chain[0] as TcpReceiver == null || ((TcpReceiver)chain[0]).Socket == null) return; IPEndPoint endPoint; try { endPoint = ((TcpReceiver)chain[0]).RemoteEndPoint; } catch { return; } Socket toDisconnect = null; lock (iocConnections) { if (!iocConnections.ContainsKey(endPoint)) return; if (Log.WillDisplay(System.Diagnostics.TraceEventType.Stop)) Log.TraceEvent(System.Diagnostics.TraceEventType.Stop, iocChains[endPoint].ChainId, "Disposing IOC chain " + endPoint); toDisconnect = iocConnections[endPoint]; iocConnections.Remove(endPoint); iocChains.Remove(endPoint); } try { toDisconnect.Disconnect(false); } catch { } // Cleanup which shall not be usefull but somehow we get wrong data.. // It's a work around not the real fix sadly. List<string> toCleanup = InfoService.ChannelEndPoint.OfType<KeyValuePair<string, Record>>() .Where(row => row.Value.Destination != null && row.Value.Destination.ToString() == endPoint.ToString()) .Select(row => row.Key).ToList(); foreach (var i in toCleanup) InfoService.ChannelEndPoint.Remove(i); chain.Gateway.DoDropIoc(endPoint.ToString()); chain.Dispose(); }
/// <summary> /// Creates a new message based on the byte buffer however use only the first "size" byte for it. /// </summary> /// <param name="buff"></param> /// <param name="size"></param> /// <param name="chain"> </param> /// <param name="reuseBuffer"></param> public static DataPacket Create(byte[] buff, int size, WorkerChain chain, bool reuseBuffer = false) { if (reuseBuffer) { DataPacket p = new DataPacket(); p.Data = buff; p.Chain = chain; p.bufferSize = size; return p; } else { DataPacket p = Create(size); p.Chain = chain; Buffer.BlockCopy(buff, 0, p.Data, 0, size); return p; } }
/// <summary> /// Creates a new message with the given payload size and sets the payload size correctly. /// </summary> /// <param name="payloadSize"></param> /// <param name="chain"> </param> public static DataPacket Create(int payloadSize, WorkerChain chain) { DataPacket p = Create(payloadSize + 16); p.Chain = chain; p.SetUInt16(2, (UInt16)payloadSize); return p; }