Exemple #1
0
        /// <summary>
        /// Called when a PUP comes in on a known socket.  Establishes a new BSP channel.
        /// A worker of the appropriate type is woken up to service the channel.
        /// </summary>
        /// <param name="p"></param>
        public static void EstablishRendezvous(PUP p, Type workerType)
        {
            if (p.Type != PupType.RFC)
            {
                Log.Write(LogType.Error, LogComponent.RTP, "Expected RFC pup, got {0}", p.Type);
                return;
            }

            UInt32 socketID = SocketIDGenerator.GetNextSocketID();

            Log.Write(LogType.Error, LogComponent.Exp, "setting up rendezvous on {0} {1} with socketID {2}", p.DestinationPort, p.SourcePort, socketID);

            BSPChannel newChannel = new BSPChannel(p, socketID);

            newChannel.OnDestroy += OnChannelDestroyed;
            _activeChannels.Add(socketID, newChannel);

            //
            // Initialize the worker for this channel.
            InitializeWorkerForChannel(newChannel, workerType);

            // Send RFC response to complete the rendezvous:

            // Modify the destination port to specify our network
            PUPPort sourcePort = p.DestinationPort;

            sourcePort.Network = DirectoryServices.Instance.LocalNetwork;
            PUP rfcResponse = new PUP(PupType.RFC, p.ID, newChannel.ClientPort, sourcePort, newChannel.ServerPort.ToArray());

            Log.Write(LogComponent.RTP,
                      "Establishing Rendezvous, ID {0}, Server port {1}, Client port {2}.",
                      p.ID, newChannel.ServerPort, newChannel.ClientPort);

            Router.Instance.SendPup(rfcResponse);
        }
Exemple #2
0
 /// <summary>
 /// Destroys and unregisters the specified channel.
 /// </summary>
 /// <param name="channel"></param>
 public static void DestroyChannel(BSPChannel channel)
 {
     // Tell the channel to shut down.  It will in turn
     // notify us when that is complete and we will remove
     // our references to it.  (See OnChannelDestroyed.)
     channel.Destroy();
 }
Exemple #3
0
        private static void InitializeWorkerForChannel(BSPChannel channel, Type workerType)
        {
            if (_workers.Count < Configuration.MaxWorkers)
            {
                // Spawn new worker, which starts it running.
                // It must be a subclass of BSPWorkerBase or this will throw.
                BSPWorkerBase worker = (BSPWorkerBase)Activator.CreateInstance(workerType, new object[] { channel });

                worker.OnExit += OnWorkerExit;
                _workers.Add(worker);
            }
            else
            {
                // Send an Abort with an informative message.
                channel.SendAbort("IFS Server full, try again later.");
            }
        }
Exemple #4
0
 public BSPWorkerBase(BSPChannel channel)
 {
     Channel = channel;
 }
Exemple #5
0
 public static void OnChannelDestroyed(BSPChannel channel)
 {
     _activeChannels.Remove(channel.ServerPort.Socket);
 }
Exemple #6
0
        /// <summary>
        /// Called when BSP-based protocols receive data.
        /// </summary>
        /// <param name="p"></param>
        public static void RecvData(PUP p)
        {
            BSPChannel channel = FindChannelForPup(p);

            if (channel == null)
            {
                Log.Write(LogType.Error, LogComponent.BSP, "Received BSP PUP on an unconnected socket, ignoring.");
                return;
            }

            Log.Write(LogType.Verbose, LogComponent.BSP, "BSP pup is {0}", p.Type);

            switch (p.Type)
            {
            case PupType.RFC:
                Log.Write(LogType.Error, LogComponent.BSP, "Received RFC on established channel, ignoring.");
                break;

            case PupType.Data:
            case PupType.AData:
            {
                channel.RecvWriteQueue(p);
            }
            break;

            case PupType.Ack:
            {
                channel.RecvAck(p);
            }
            break;

            case PupType.End:
            {
                // Second step of tearing down a connection, the End from the client, to which we will
                // send an EndReply, expecting a second EndReply.
                channel.End(p);
            }
            break;

            case PupType.EndReply:
            {
                // Last step of tearing down a connection, the EndReply from the client.
                DestroyChannel(channel);
            }
            break;

            case PupType.Mark:
            case PupType.AMark:
            {
                channel.RecvWriteQueue(p);
            }
            break;

            case PupType.Abort:
            {
                string abortMessage = Helpers.ArrayToString(p.Contents);
                Log.Write(LogType.Warning, LogComponent.RTP, String.Format("BSP aborted, message from client: '{0}'", abortMessage));

                DestroyChannel(channel);
            }
            break;

            case PupType.Error:
            {
                channel.RecvError(p);
            }
            break;

            case PupType.Interrupt:
            {
                channel.RecvInterrupt(p);
            }
            break;

            default:
                throw new NotImplementedException(String.Format("Unhandled BSP PUP type {0}.", p.Type));
            }
        }