public override void DoRequest(DataPacket packet, Workers.WorkerChain chain, DataPacketDelegate sendData) { DataPacket newPacket = (DataPacket)packet.Clone(); UInt32 gwioid = CidGenerator.Next(); Record record = InfoService.IOID.Create(gwioid); record.Destination = packet.Sender; record.IOID = packet.Parameter2; record = InfoService.ChannelCid[packet.Parameter1]; // Lost the CID if (record == null) { if (Log.WillDisplay(TraceEventType.Error)) Log.TraceEvent(System.Diagnostics.TraceEventType.Error, chain.ChainId, "Readnotify not linked to a correct channel"); packet.Chain.Dispose(); return; } if (record.SID == null) { if (Log.WillDisplay(TraceEventType.Error)) Log.TraceEvent(System.Diagnostics.TraceEventType.Error, chain.ChainId, "Readnotify without SID"); chain.Dispose(); return; } newPacket.Destination = record.Destination; newPacket.Parameter1 = record.SID.Value; newPacket.Parameter2 = gwioid; sendData(newPacket); }
public override void DoRequest(DataPacket packet, PBCaGw.Workers.WorkerChain chain, DataPacketDelegate sendData) { /*DataPacket newPacket = (DataPacket)packet.Clone(); newPacket.Destination = packet.Sender; newPacket.DataType = 0; newPacket.DataCount = Gateway.CA_PROTO_VERSION; SendData(newPacket);*/ }
public override void DoResponse(DataPacket packet, Workers.WorkerChain chain, DataPacketDelegate sendData) { Record record = InfoService.ChannelCid[packet.Parameter1]; if (Log.WillDisplay(TraceEventType.Critical)) { if (record != null) Log.TraceEvent(TraceEventType.Critical, chain.ChainId, "Proto Error (" + packet.Parameter2 + ") on CID: " + packet.Parameter1 + " (" + record.Channel + "), SID = " + record.SID); else Log.TraceEvent(TraceEventType.Critical, chain.ChainId, "Proto Error (" + packet.Parameter2 + ") on CID: " + packet.Parameter1); } }
public override void DoResponse(DataPacket packet, Workers.WorkerChain chain, DataPacketDelegate sendData) { DataPacket newPacket = (DataPacket)packet.Clone(); Record record = InfoService.IOID[packet.Parameter2]; if (record == null || record.IOID == null) return; InfoService.IOID.Remove(packet.Parameter2); CidGenerator.ReleaseCid(packet.Parameter2); newPacket.Destination = record.Destination; newPacket.Parameter2 = record.IOID.Value; sendData(newPacket); }
public override void DoRequest(DataPacket packet, Workers.WorkerChain chain, DataPacketDelegate sendData) { try { EventAdd.Unsubscribe(chain.Subscriptions[packet.Parameter2]); uint res; chain.Subscriptions.TryRemove(packet.Parameter2, out res); } catch { if (Log.WillDisplay(System.Diagnostics.TraceEventType.Critical)) Log.TraceEvent(System.Diagnostics.TraceEventType.Critical, chain.ChainId, "Error while cancelling a monitor."); chain.Dispose(); } }
public override void DoResponse(DataPacket packet, Workers.WorkerChain chain, DataPacketDelegate sendData) { DataPacket newPacket = (DataPacket)packet.Clone(); Record record = InfoService.IOID[packet.Parameter2]; if (record == null) return; // Removes it to avoid the cleaup InfoService.IOID.Remove(packet.Parameter2); CidGenerator.ReleaseCid(packet.Parameter2); lock (EventAdd.lockObject) { // It's the initial answer as get of "cached" monitor. if (record.IOID.HasValue && record.IOID.Value == 0) { if (!record.SID.HasValue) return; if (record.CID.HasValue && InfoService.ChannelSubscription.Knows(record.CID.Value)) { if (InfoService.ChannelSubscription[record.CID.Value].PacketCount == 0 && InfoService.ChannelSubscription[record.CID.Value].FirstValue == true) { if (Log.WillDisplay(TraceEventType.Verbose)) Log.TraceEvent(TraceEventType.Verbose, chain.ChainId, "Sending readnotify data on " + record.SID.Value); newPacket.Command = 1; newPacket.Parameter1 = 1; newPacket.Parameter2 = record.SID.Value; newPacket.Destination = record.Destination; newPacket.DataCount = record.DataCount.Value; newPacket.DataType = record.DBRType.Value; sendData(newPacket); InfoService.ChannelSubscription[record.CID.Value].FirstValue = false; InfoService.ChannelSubscription[record.CID.Value].PacketCount = 1; } } return; } } newPacket.Destination = record.Destination; newPacket.Parameter1 = 1; newPacket.Parameter2 = record.IOID.Value; sendData(newPacket); }
public override void DoRequest(DataPacket packet, Workers.WorkerChain chain, DataPacketDelegate sendData) { Record channelInfo = InfoService.ChannelCid[packet.Parameter1]; // Lost the CID if (channelInfo == null) { if (Log.WillDisplay(System.Diagnostics.TraceEventType.Error)) Log.TraceEvent(System.Diagnostics.TraceEventType.Error, chain.ChainId, "Write not linked to a correct channel"); packet.Chain.Dispose(); return; } SecurityAccess access; switch (chain.Side) { case Workers.ChainSide.SIDE_A: access = chain.Gateway.Configuration.Security.EvaluateSideA(channelInfo.Channel, chain.Username, chain.Hostname, packet.Sender.Address.ToString()); break; default: access = chain.Gateway.Configuration.Security.EvaluateSideB(channelInfo.Channel, chain.Username, chain.Hostname, packet.Sender.Address.ToString()); break; } // We don't have write access quit! if (!access.Has(SecurityAccess.WRITE)) { return; } DataPacket newPacket = (DataPacket)packet.Clone(); UInt32 gwioid = CidGenerator.Next(); newPacket.Destination = channelInfo.Destination; // No SID? Can't write if (channelInfo.SID == null) { if (Log.WillDisplay(TraceEventType.Critical)) Log.TraceEvent(TraceEventType.Critical, chain.ChainId, "Write without SID"); WorkerChain ioc = TcpManager.GetIocChain(null, channelInfo.Destination); if (ioc != null) ioc.Dispose(); chain.Dispose(); return; } newPacket.Parameter1 = channelInfo.SID.Value; newPacket.Parameter2 = gwioid; sendData(newPacket); }
public override void DoRequest(DataPacket packet, Workers.WorkerChain chain, DataPacketDelegate sendData) { IPAddress senderAddress=packet.Sender.Address; if (senderAddress.Equals(chain.Gateway.Configuration.LocalSideA.Address) || senderAddress.Equals(chain.Gateway.Configuration.LocalSideB.Address)) return; // Use only the 5th beacon as restart if (packet.Parameter1 != 5) return; // Reset the beacon sender if (chain.Side == Workers.ChainSide.SIDE_A && chain.Gateway.beaconB != null) chain.Gateway.beaconB.ResetBeacon(); else if (chain.Side == Workers.ChainSide.SIDE_B && chain.Gateway.beaconA != null) chain.Gateway.beaconA.ResetBeacon(); }
/// <summary> /// Both request / answer should be handled in the same way. /// If we didn't sent the first packet then we should answer, /// otherwise it's the answer to our own echo, therefore drop it. /// </summary> /// <param name="packet"></param> /// <param name="chain"></param> void HandleEcho(DataPacket packet, Workers.WorkerChain chain, DataPacketDelegate SendData) { // Answer to our own? if (InfoService.EchoSent[packet.Sender] != null) { // Yes then drop the packet and remove the info from our list InfoService.EchoSent.Remove(packet.Sender); } else { // No then let's answer with the same content just changing the destination as the sender DataPacket newPacket = (DataPacket)packet.Clone(); newPacket.Destination = packet.Sender; //newPacket.NeedToFlush = true; SendData(newPacket); } }
public override void DoRequest(DataPacket packet, Workers.WorkerChain chain, DataPacketDelegate sendData) { chain.Username = packet.GetDataAsString(); }
/// <summary> /// Doesn't have a response for this message /// </summary> /// <param name="packet"></param> /// <param name="chain"></param> /// <param name="sendData"> </param> public override void DoResponse(DataPacket packet, Workers.WorkerChain chain, DataPacketDelegate sendData) { }
public override void DoRequest(DataPacket packet, Workers.WorkerChain chain, DataPacketDelegate sendData) { if (packet.DataCount == 0) { if (Log.WillDisplay(TraceEventType.Error)) Log.TraceEvent(TraceEventType.Error, chain.ChainId, "Event add with datacount == 0!"); packet.DataCount = 1; } lock (lockObject) { Record record = InfoService.ChannelCid[packet.Parameter1]; // Lost the CID... if (record == null) { if (Log.WillDisplay(TraceEventType.Error)) Log.TraceEvent(System.Diagnostics.TraceEventType.Error, chain.ChainId, "EventAdd not linked to a correct channel"); packet.Chain.Dispose(); return; } if (record.SID == null) { if (Log.WillDisplay(TraceEventType.Error)) Log.TraceEvent(System.Diagnostics.TraceEventType.Error, chain.ChainId, "EventAdd SID null"); packet.Chain.Dispose(); return; } if (Log.WillDisplay(TraceEventType.Information)) Log.TraceEvent(System.Diagnostics.TraceEventType.Information, chain.ChainId, "Add event for " + record.Channel); // Not enough info if (packet.MessageSize < 12 + 2 + packet.HeaderSize) { } string recId = record.Channel + "/" + packet.DataType + "/" + packet.DataCount + "/" + packet.GetUInt16(12 + (int)packet.HeaderSize); //Console.WriteLine(recId); //recId = ""+CidGenerator.Next(); UInt32 gwcid = CidGenerator.Next(); Record currentMonitor = InfoService.ChannelSubscription.Create(gwcid); currentMonitor.Destination = record.Destination; currentMonitor.DBRType = packet.DataType; currentMonitor.DataCount = packet.DataCount; currentMonitor.Client = packet.Sender; currentMonitor.SubscriptionId = packet.Parameter2; currentMonitor.SID = record.SID.Value; currentMonitor.Channel = recId; currentMonitor.FirstValue = false; chain.Subscriptions[packet.Parameter2] = gwcid; // A new monitor // Create a new subscription for the main channel // And create a list of subscriptions if (!InfoService.SubscribedChannel.Knows(recId)) { if (Log.WillDisplay(TraceEventType.Information)) Log.TraceEvent(System.Diagnostics.TraceEventType.Information, chain.ChainId, "Creating new monitor monitor"); // Create the subscriptions record. Record subscriptions = new Record(); subscriptions.SubscriptionList = new ConcurrentBag<UInt32>(); subscriptions.SubscriptionList.Add(gwcid); subscriptions.FirstValue = true; InfoService.SubscribedChannel[recId] = subscriptions; // We don't need to skip till the first packet. currentMonitor.PacketCount = 1; gwcid = CidGenerator.Next(); subscriptions.GWCID = gwcid; WorkerChain ioc = TcpManager.GetIocChain((packet.Chain == null ? null : packet.Chain.Gateway), record.Destination); if (ioc == null) { if (Log.WillDisplay(TraceEventType.Error)) Log.TraceEvent(System.Diagnostics.TraceEventType.Error, chain.ChainId, "Lost IOC"); chain.Dispose(); return; } ioc.ChannelSubscriptions[recId] = gwcid; currentMonitor = InfoService.ChannelSubscription.Create(gwcid); currentMonitor.Channel = recId; currentMonitor.Destination = record.Destination; currentMonitor.SID = record.SID; currentMonitor.DBRType = packet.DataType; currentMonitor.DataCount = packet.DataCount; DataPacket newPacket = (DataPacket)packet.Clone(); newPacket.Parameter1 = record.SID.Value; newPacket.Parameter2 = gwcid; newPacket.Destination = record.Destination; sendData(newPacket); } else { Record subscriptions = null; if (Log.WillDisplay(TraceEventType.Information)) Log.TraceEvent(System.Diagnostics.TraceEventType.Information, chain.ChainId, "Linking to existing monitor"); // Add ourself to the subscriptions subscriptions = InfoService.SubscribedChannel[recId]; if (subscriptions == null) { if (Log.WillDisplay(TraceEventType.Error)) Log.TraceEvent(System.Diagnostics.TraceEventType.Error, chain.ChainId, "Lost main monitor"); chain.Dispose(); return; } subscriptions.SubscriptionList.Add(gwcid); // Channel never got the first answer // So let's wait like the others if (subscriptions.FirstValue) { currentMonitor.FirstValue = true; currentMonitor.PacketCount = 1; } // Channel already got the first answer // Send a ReadNotify to get the first value else { /*DataPacket newPacket = (DataPacket)subscriptions.FirstPacket.Clone(); newPacket.Destination = packet.Sender; newPacket.Parameter2 = packet.Parameter2; newPacket.Sender = packet.Sender; sendData(newPacket);*/ currentMonitor.FirstValue = true; currentMonitor.PacketCount = 0; UInt32 gwioid = CidGenerator.Next(); // Send an intial read-notify DataPacket newPacket = DataPacket.Create(0, packet.Chain); newPacket.Command = 15; newPacket.DataCount = packet.DataCount; newPacket.DataType = packet.DataType; newPacket.Parameter1 = record.SID.Value; newPacket.Parameter2 = gwioid; newPacket.Destination = record.Destination; record = InfoService.IOID.Create(gwioid); record.Destination = packet.Sender; record.IOID = 0; record.SID = packet.Parameter2; record.DBRType = packet.DataType; record.DataCount = packet.DataCount; record.CID = gwcid; sendData(newPacket); } } } }
public override void DoResponse(DataPacket packet, Workers.WorkerChain chain, DataPacketDelegate sendData) { HandleEcho(packet, chain, sendData); }
public override void DoResponse(DataPacket packet, Workers.WorkerChain chain, DataPacketDelegate sendData) { if (!InfoService.ChannelCid.Knows(packet.Parameter1)) // Response too late, we drop it. { if (Log.WillDisplay(TraceEventType.Verbose)) Log.TraceEvent(System.Diagnostics.TraceEventType.Verbose, (packet.Chain == null ? 0 : packet.Chain.ChainId), "Drop late reponse."); return; } Record record = InfoService.ChannelCid[packet.Parameter1]; if (record.Channel == null) // Response too late, we drop it. { if (Log.WillDisplay(TraceEventType.Verbose)) Log.TraceEvent(System.Diagnostics.TraceEventType.Verbose, (packet.Chain == null ? 0 : packet.Chain.ChainId), "Drop late reponse."); return; } if (Log.WillDisplay(TraceEventType.Verbose)) Log.TraceEvent(System.Diagnostics.TraceEventType.Verbose, (packet.Chain == null ? 0 : packet.Chain.ChainId), "Got response for " + record.Channel + "."); record.SID = packet.Parameter2; if(!chain.Channels.Any(row=>row == record.Channel)) chain.Channels.Add(record.Channel); object lockOper = locks.GetOrAdd(record.Channel, new object()); // Stores in the channel end point the retreiven info Record channelInfo; lock (lockOper) //if(true) { channelInfo = InfoService.ChannelEndPoint[record.Channel]; if (channelInfo == null) { if (Log.WillDisplay(TraceEventType.Error)) Log.TraceEvent(System.Diagnostics.TraceEventType.Error, (packet.Chain == null ? 0 : packet.Chain.ChainId), "Got create channel response, but lost the request."); return; } channelInfo.SID = packet.Parameter2; channelInfo.DBRType = packet.DataType; channelInfo.DataCount = packet.DataCount; channelInfo.GWCID = packet.Parameter1; } channelInfo.Notify(chain, packet); // Was a prepared creation, let's stop if (record.Client != null && record.Channel != null) { WorkerChain destChain = TcpManager.GetClientChain(record.Client); if (destChain != null) { Log.TraceEvent(TraceEventType.Verbose, chain.ChainId, "Direct responce create channel cid " + destChain.ChannelCid[record.Channel]); // Give back access rights before the create channel DataPacket accessPacket = DataPacket.Create(0, packet.Chain); accessPacket.Command = 22; accessPacket.DataType = 0; accessPacket.DataCount = 0; accessPacket.Parameter1 = destChain.ChannelCid[record.Channel]; accessPacket.Parameter2 = (uint)record.AccessRight; accessPacket.Sender = packet.Sender; accessPacket.Destination = record.Client; sendData(accessPacket); DataPacket newPacket = (DataPacket)packet.Clone(); newPacket.Parameter1 = destChain.ChannelCid[record.Channel]; newPacket.Parameter2 = packet.Parameter1; newPacket.Destination = record.Client; sendData(newPacket); } } }
public override void DoResponse(DataPacket packet, Workers.WorkerChain chain, DataPacketDelegate sendData) { lock (lockObject) { if (packet.PayloadSize == 0) { // Closing channel. return; } Record mainSubscription = InfoService.ChannelSubscription[packet.Parameter2]; if (mainSubscription == null) { /*if (Log.WillDisplay(TraceEventType.Error)) Log.TraceEvent(TraceEventType.Error, chain.ChainId, "Main monitor not found.");*/ //chain.Dispose(); return; } string recId = mainSubscription.Channel; Record subscriptions = InfoService.SubscribedChannel[recId]; if (subscriptions == null) { if (Log.WillDisplay(TraceEventType.Error)) Log.TraceEvent(TraceEventType.Error, chain.ChainId, "Subscription list not found not found."); chain.Dispose(); return; } // Keep a copy of the first packet. /*if (subscriptions.FirstPacket == null) subscriptions.FirstPacket = (DataPacket)packet.Clone();*/ subscriptions.FirstValue = false; foreach (UInt32 i in subscriptions.SubscriptionList) { DataPacket newPacket = (DataPacket)packet.Clone(); Record subscription = InfoService.ChannelSubscription[i]; // Received a response after killing it maybe if (subscription == null || subscription.SubscriptionId == null) continue; if (subscription.PacketCount == 0 && subscription.FirstValue == true) { //subscription.PacketCount++; continue; } subscription.PacketCount++; newPacket.Destination = subscription.Client; newPacket.Parameter2 = subscription.SubscriptionId.Value; // Event cancel send a command 1 as response (as event add) // To see the difference check the payload as the event cancel always have a payload of 0 if (packet.PayloadSize == 0) { InfoService.ChannelSubscription.Remove(packet.Parameter2); CidGenerator.ReleaseCid(packet.Parameter2); WorkerChain clientChain = TcpManager.GetClientChain(newPacket.Destination); if (clientChain != null) { uint val; clientChain.Subscriptions.TryRemove(newPacket.Parameter2, out val); } continue; } sendData(newPacket); } } }
public override void DoRequest(DataPacket packet, Workers.WorkerChain chain, DataPacketDelegate sendData) { /*Stopwatch sw = new Stopwatch(); sw.Start();*/ string channelName = packet.GetDataAsString(); Record channelInfo = null; // Get a lock object for this particula channel name object lockOper = locks.GetOrAdd(channelName, new object()); //if (InfoService.ChannelEndPoint.Knows(channelName)) channelInfo = InfoService.ChannelEndPoint[channelName]; // Never got this channel! if (channelInfo == null) { StorageService<string> searchService; if (chain.Side == ChainSide.SIDE_A) searchService = InfoService.SearchChannelEndPointA; else searchService = InfoService.SearchChannelEndPointB; if (!searchService.Knows(channelName)) { if (Log.WillDisplay(TraceEventType.Error)) Log.TraceEvent(TraceEventType.Error, chain.ChainId, "Created channel (" + channelName + ") without knowing where it should point at..."); chain.Dispose(); return; } channelInfo = searchService[channelName]; channelInfo.ChainSide = chain.Side; InfoService.ChannelEndPoint[channelName] = channelInfo; channelInfo.GWCID = null; } //Console.WriteLine("Create 1: " + sw.Elapsed); if (Log.WillDisplay(TraceEventType.Verbose)) Log.TraceEvent(TraceEventType.Verbose, chain.ChainId, "Request " + channelName + " with cid " + packet.Parameter1); SecurityAccess access; switch (chain.Side) { case Workers.ChainSide.SIDE_A: access = chain.Gateway.Configuration.Security.EvaluateSideA(channelName, chain.Username, chain.Hostname, packet.Sender.Address.ToString()); break; default: access = chain.Gateway.Configuration.Security.EvaluateSideB(channelName, chain.Username, chain.Hostname, packet.Sender.Address.ToString()); break; } // Don't have the right, return a fail create channel if (!access.Has(SecurityAccess.READ)) { if (Log.WillDisplay(TraceEventType.Warning)) Log.TraceEvent(System.Diagnostics.TraceEventType.Warning, packet.Chain.ChainId, "Create channel " + channelName + " from " + packet.Sender + " while not having rights to read"); DataPacket newPacket = DataPacket.Create(0, chain); newPacket.Command = 26; newPacket.Parameter1 = packet.Parameter1; newPacket.Sender = packet.Sender; newPacket.Destination = packet.Sender; sendData(newPacket); return; } var knownGWCID = false; var knownSID = false; lock (lockOper) { knownGWCID = channelInfo.GWCID.HasValue; knownSID = channelInfo.SID.HasValue; } // We never got back any answer, let's trash the GWCID to re-create it if (knownGWCID && !knownSID && (Gateway.Now - channelInfo.CreatedOn).TotalSeconds > 10) { channelInfo.GWCID = null; knownGWCID = false; } // Checks if we have already a channel open with the IOC or not // If we have it we can answer directly if (knownGWCID) { //Console.WriteLine("Create 2: " + sw.Elapsed); if (Log.WillDisplay(TraceEventType.Verbose)) Log.TraceEvent(System.Diagnostics.TraceEventType.Verbose, (packet.Chain == null ? 0 : packet.Chain.ChainId), "Request of a known channel (" + channelName + ")"); // We need to check if this is something currently in creation // Seems we know all if (knownSID) { Log.TraceEvent(TraceEventType.Verbose, chain.ChainId, "Cached responce create channel cid " + packet.Parameter1); // Give back access rights before the create channel DataPacket newPacket = DataPacket.Create(0, packet.Chain); newPacket.Command = 22; newPacket.DataType = 0; newPacket.DataCount = 0; newPacket.Parameter1 = packet.Parameter1; newPacket.Parameter2 = (uint)access; newPacket.Sender = packet.Sender; newPacket.Destination = packet.Sender; sendData(newPacket); // Gives the create channel answer newPacket = DataPacket.Create(0, packet.Chain); newPacket.Command = 18; // ReSharper disable PossibleInvalidOperationException newPacket.DataType = channelInfo.DBRType.Value; // ReSharper restore PossibleInvalidOperationException // ReSharper disable PossibleInvalidOperationException newPacket.DataCount = channelInfo.DataCount.Value; // ReSharper restore PossibleInvalidOperationException newPacket.Parameter1 = packet.Parameter1; newPacket.Parameter2 = channelInfo.GWCID.Value; newPacket.Sender = packet.Sender; newPacket.Destination = packet.Sender; sendData(newPacket); chain.ChannelCid[channelName] = packet.Parameter1; // We have all the info we can continue. chain.Gateway.DoClientConnectedChannels(chain.ClientEndPoint.ToString(), channelName); //Console.WriteLine("Create 2.1: " + sw.Elapsed); return; } // Still in creation then let's wait till the channel actually is created lock (lockOper) { uint clientCid = packet.Parameter1; IPEndPoint clientIp = packet.Sender; Log.TraceEvent(TraceEventType.Verbose, chain.ChainId, "Add event for " + clientCid); channelInfo.GetNotification += delegate(object sender, DataPacket receivedPacket) { //Console.WriteLine("Create 5: " + sw.Elapsed); Record record = InfoService.ChannelCid[receivedPacket.Parameter1]; if (record == null || record.Channel == null) // Response too late, we drop it. return; Record resChannelInfo = InfoService.ChannelEndPoint[record.Channel]; if (resChannelInfo == null) return; Log.TraceEvent(TraceEventType.Verbose, chain.ChainId, "Event responce create channel cid " + clientCid); // Give back access rights before the create channel DataPacket resPacket = DataPacket.Create(0, packet.Chain); resPacket.Command = 22; resPacket.DataType = 0; resPacket.DataCount = 0; //resPacket.Parameter1 = packet.Parameter1; resPacket.Parameter1 = clientCid; resPacket.Parameter2 = (uint)access; resPacket.Sender = clientIp; resPacket.Destination = clientIp; TcpManager.SendClientPacket(resPacket); resPacket = (DataPacket)receivedPacket.Clone(); resPacket.Command = 18; resPacket.Destination = clientIp; resPacket.Parameter1 = clientCid; resPacket.Parameter2 = channelInfo.GWCID.Value; resPacket.Sender = clientIp; TcpManager.SendClientPacket(resPacket); chain.ChannelCid[channelName] = clientCid; chain.Gateway.DoClientConnectedChannels(chain.ClientEndPoint.ToString(), channelName); }; } } // We don't have, we need therefore to connect to the IOC to create one else { //Console.WriteLine("Create 3: " + sw.Elapsed); /*if (chain.ChannelCid.ContainsKey(channelName)) { if (Log.WillDisplay(TraceEventType.Warning)) Log.TraceEvent(System.Diagnostics.TraceEventType.Warning, (packet.Chain == null ? 0 : packet.Chain.ChainId), "Duplicated request (" + channelName + ")"); }*/ if (Log.WillDisplay(TraceEventType.Verbose)) Log.TraceEvent(System.Diagnostics.TraceEventType.Verbose, (packet.Chain == null ? 0 : packet.Chain.ChainId), "Request of a new channel (" + channelName + ")"); channelInfo.GWCID = packet.Parameter1; UInt32 gwcid = CidGenerator.Next(); Record record = InfoService.ChannelCid.Create(gwcid); record.Channel = channelName; record.GWCID = gwcid; record.Client = packet.Sender; record.AccessRight = access; record.Destination = channelInfo.Server; record.ChainSide = chain.Side; chain.ChannelCid[channelName] = packet.Parameter1; // Send create channel DataPacket newPacket = (DataPacket)packet.Clone(); newPacket.Parameter1 = gwcid; // Version newPacket.Parameter2 = Gateway.CA_PROTO_VERSION; newPacket.Destination = channelInfo.Server; sendData(newPacket); chain.Gateway.DoClientConnectedChannels(chain.ClientEndPoint.ToString(), channelName); } //Console.WriteLine("Create 6: " + sw.Elapsed); }
/// <summary> /// Closing channel is currently simply answering as if we do it... but in fact does nothing. /// </summary> /// <param name="packet"></param> /// <param name="chain"></param> /// <param name="sendData"> </param> public override void DoRequest(DataPacket packet, Workers.WorkerChain chain, DataPacketDelegate sendData) { DataPacket newPacket = (DataPacket)packet.Clone(); newPacket.Destination = packet.Sender; sendData(newPacket); }
/// <summary> /// Used to answer to a response /// </summary> /// <param name="command"></param> /// <param name="packet"></param> /// <param name="chain"></param> /// <param name="send"> </param> /// <returns></returns> public static void ExecuteResponseHandler(UInt16 command, DataPacket packet, PBCaGw.Workers.WorkerChain chain, DataPacketDelegate send) { if (!(command >= handlers.Length || handlers[command] == null)) handlers[command].DoResponse(packet, chain, send); }
public override void DoRequest(DataPacket packet, PBCaGw.Workers.WorkerChain chain, DataPacketDelegate sendData) { // From ourself? Skip it. if (packet.Sender.Equals(chain.ClientEndPoint)) return; /*// Not coming from one of the allowed destination if (chain.Destinations.Any(i => CompareNetC(i.Address, packet.Sender.Address))) return;*/ if (chain.Destinations == null) return; if (packet.Sender == null) return; if (Log.WillDisplay(TraceEventType.Verbose)) Log.TraceEvent(System.Diagnostics.TraceEventType.Verbose, chain.ChainId, "Search from: " + packet.Sender); //if(chain.Gateway.Configuration.LocalSideA.Port == chain.Gateway.Configuration.LocalSideB.Port) // It's a response //if (packet.PayloadSize <= 8 && packet.Chain.Gateway.Configuration.ConfigurationType == ConfigurationType.BIDIRECTIONAL) if (packet.PayloadSize == 8) { DoResponse(packet, chain, sendData); return; } DiagnosticServer.NbSearches++; DataPacket newPacket = (DataPacket)packet.Clone(); string channelName = packet.GetDataAsString(); if (chain.Side == Workers.ChainSide.SIDE_A) { if (!chain.Gateway.Configuration.Security.EvaluateSideA(channelName, null, null, packet.Sender.Address.ToString()).Has(SecurityAccess.READ)) return; } else { if (!chain.Gateway.Configuration.Security.EvaluateSideB(channelName, null, null, packet.Sender.Address.ToString()).Has(SecurityAccess.READ)) return; } Record record; // Maybe this request is known. if (InfoService.ChannelEndPoint.Knows(channelName)) { record = InfoService.ChannelEndPoint[channelName]; bool knownChannel = false; if (chain.Side == ChainSide.SIDE_A && record.knownFromSideA == true) knownChannel=true; else if (chain.Side == ChainSide.SIDE_B && record.knownFromSideB == true) knownChannel=true; if(knownChannel) { if (Log.WillDisplay(TraceEventType.Information)) Log.TraceEvent(TraceEventType.Information, chain.ChainId, "Cached search " + channelName); newPacket = DataPacket.Create(8, packet.Chain); newPacket.ReverseAnswer = true; newPacket.Command = 6; newPacket.Parameter1 = 0xffffffff; newPacket.Parameter2 = packet.Parameter1; if (chain.Side == Workers.ChainSide.SIDE_A) newPacket.DataType = (UInt16)chain.Gateway.Configuration.LocalSideA.Port; else newPacket.DataType = (UInt16)chain.Gateway.Configuration.LocalSideB.Port; newPacket.DataCount = 0; newPacket.SetUInt16(16, Gateway.CA_PROTO_VERSION); newPacket.Destination = packet.Sender; sendData(newPacket); return; } } if (chain.Side == ChainSide.SIDE_A) record = InfoService.SearchChannelEndPointA[channelName]; else record = InfoService.SearchChannelEndPointB[channelName]; // We have the info stored in the channel end point? Yes let's use it then. /*if (record == null && InfoService.ChannelEndPoint.Knows(channelName)) { record = InfoService.ChannelEndPoint[channelName]; }*/ // First time, or never got answer, let's ask to the IOCS // Step 1 if (record == null) { record = InfoService.SearchChannel.Create(); // ReSharper disable PossibleInvalidOperationException uint gwcid = record.GWCID.Value; // ReSharper restore PossibleInvalidOperationException record.CID = packet.Parameter1; record.Client = packet.Sender; record.Channel = channelName; // Diagnostic search newPacket = (DataPacket)packet.Clone(); newPacket.Parameter1 = gwcid; newPacket.Parameter2 = gwcid; newPacket.Destination = new IPEndPoint(chain.Gateway.Configuration.LocalSideB.Address, 7890); if (chain.Side == Workers.ChainSide.SIDE_B) newPacket.ReverseAnswer = true; sendData(newPacket); foreach (IPEndPoint dest in chain.Destinations) { newPacket = (DataPacket)packet.Clone(); newPacket.Parameter1 = gwcid; newPacket.Parameter2 = gwcid; newPacket.Destination = dest; sendData(newPacket); } } // We have the info, therefore use the stored info to answer (cached) else { newPacket = DataPacket.Create(8, packet.Chain); newPacket.ReverseAnswer = true; newPacket.Command = 6; newPacket.Parameter1 = 0xffffffff; newPacket.Parameter2 = packet.Parameter1; if (chain.Side == Workers.ChainSide.SIDE_A) newPacket.DataType = (UInt16)chain.Gateway.Configuration.LocalSideA.Port; else newPacket.DataType = (UInt16)chain.Gateway.Configuration.LocalSideB.Port; newPacket.DataCount = 0; newPacket.SetUInt16(16, Gateway.CA_PROTO_VERSION); newPacket.Destination = packet.Sender; sendData(newPacket); } }
// We get back the answer from the IOC public override void DoResponse(DataPacket packet, Workers.WorkerChain chain, DataPacketDelegate sendData) { Record record = InfoService.SearchChannel[packet.Parameter2]; if (record == null) return; // Let's create the channel in parallel. That should speedup the communication. string channelName = record.Channel; if (Gateway.AutoCreateChannel) { if (!InfoService.ChannelEndPoint.Knows(channelName)) { Record channelInfo = InfoService.ChannelEndPoint[channelName]; if (Log.WillDisplay(TraceEventType.Information)) Log.TraceEvent(TraceEventType.Information, chain.ChainId, "Pre-create the channel " + channelName); UInt32 gwcid = CidGenerator.Next(); channelInfo = InfoService.ChannelEndPoint.Create(record.Channel); channelInfo.Destination = new IPEndPoint(packet.Sender.Address, packet.DataType); channelInfo.GWCID = gwcid; record = InfoService.ChannelCid.Create(gwcid); record.Channel = channelName; record.GWCID = gwcid; record.Destination = new IPEndPoint(packet.Sender.Address, packet.DataType); DataPacket channelPacket = DataPacket.Create(16 + channelName.Length + DataPacket.Padding(channelName.Length)); channelPacket.PayloadSize = (ushort)(channelName.Length + DataPacket.Padding(channelName.Length)); channelPacket.DataType = 0; channelPacket.DataCount = 0; channelPacket.Command = 18; channelPacket.Parameter1 = gwcid; // Version channelPacket.Parameter2 = Gateway.CA_PROTO_VERSION; IPEndPoint dest = new IPEndPoint(packet.Sender.Address, packet.DataType); channelPacket.Destination = dest; //channelPacket.NeedToFlush = true; channelPacket.SetDataAsString(channelName); Gateway gw = packet.Chain.Gateway; System.Threading.ThreadPool.QueueUserWorkItem(state => { try { TcpManager.SendIocPacket(gw, channelPacket); //TcpManager.FlushBuffer(dest); } catch { } }); record = InfoService.SearchChannel[packet.Parameter2]; } } if (chain.Side == ChainSide.SIDE_B || chain.Side == ChainSide.UDP_RESP_SIDE_A) InfoService.SearchChannelEndPointA.Remove(channelName); else InfoService.SearchChannelEndPointB.Remove(channelName); IPEndPoint destination = new IPEndPoint(packet.Sender.Address, packet.DataType); WorkerChain ioc = TcpManager.GetIocChain(chain.Gateway, destination); // We can't connect to the IOC... if (ioc == null) return; if (!ioc.Channels.Any(row => row == channelName)) ioc.Channels.Add(channelName); Record channel = InfoService.ChannelEndPoint[channelName]; if (channel == null) channel = InfoService.ChannelEndPoint.Create(channelName); channel.Server = destination; if (chain.Side == ChainSide.SIDE_B || chain.Side == ChainSide.UDP_RESP_SIDE_A) channel.knownFromSideA = true; else channel.knownFromSideA = false; if (record == null || record.CID == null) return; // Auto-creation of the channels after a restart if (record.CID == 0) { if (Log.WillDisplay(TraceEventType.Information)) Log.TraceEvent(TraceEventType.Information, chain.ChainId, "Recovered channel " + channelName); return; } DataPacket newPacket = (DataPacket)packet.Clone(); if (packet.Chain.Gateway.Configuration.ConfigurationType == ConfigurationType.BIDIRECTIONAL) { if (chain.Side == Workers.ChainSide.SIDE_A) newPacket.DataType = (UInt16)chain.Gateway.Configuration.LocalSideB.Port; else newPacket.DataType = (UInt16)chain.Gateway.Configuration.LocalSideA.Port; } else if (chain.Side == Workers.ChainSide.UDP_RESP_SIDE_A) newPacket.DataType = (UInt16)chain.Gateway.Configuration.LocalSideA.Port; else newPacket.DataType = (UInt16)chain.Gateway.Configuration.LocalSideB.Port; newPacket.Parameter1 = 0xffffffff; newPacket.Parameter2 = record.CID.Value; newPacket.Destination = record.Client; newPacket.SetUInt16(16, Gateway.CA_PROTO_VERSION); sendData(newPacket); }
public abstract void DoResponse(DataPacket packet, Workers.WorkerChain chain, DataPacketDelegate sendData);
/// <summary> /// Doesn't have a response for this message /// </summary> /// <param name="packet"></param> /// <param name="chain"></param> public override void DoResponse(DataPacket packet, Workers.WorkerChain chain, DataPacketDelegate sendData) { throw new NotImplementedException(); }