Ejemplo n.º 1
0
        private void SendGatewayInformationResponse(PUP p)
        {
            //
            // Pup Type: 201 (octal)
            // Pup ID: same as in Request Pup
            // Pup Contents: one or more groups of four bytes, each providing routing information for
            // one network, as follows:
            //
            //    <target-net> <gateway-net> <gateway-host> <hop-count>
            //
            // In each group, the first byte specifies the target network number. If the gateway host is
            // directly connected to that network, then the <hop-count> is zero and the <gateway-net> and
            // <gateway-host> describe the gateway’s connection to the network.
            // If the gateway host is not directly connected to the target network, then the second and
            // third bytes give the network and host numbers of another gateway through which the
            // responding gateway routes Pups to that network, and the fourth byte gives the hop count,
            // i.e., the number of additional gateways (not including itself) through which the responding
            // gateway believes a Pup must pass to reach the specified network. A hop count greater than
            // the constant maxHops (presently 15) signifies that the target network is believed to be
            // inaccessible.
            //


            byte[] infoArray = GetGatewayInformationArray();

            PUPPort localPort = new PUPPort(DirectoryServices.Instance.LocalHostAddress, p.DestinationPort.Socket);

            // Response must contain our network number; this is used to tell clients what network they're on if they don't already know.
            PUPPort remotePort = new PUPPort(DirectoryServices.Instance.LocalNetwork, p.SourcePort.Host, p.SourcePort.Socket);

            PUP response = new PUP(PupType.GatewayInformationResponse, p.ID, remotePort, localPort, infoArray);

            Router.Instance.SendPup(response);
        }
Ejemplo n.º 2
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);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Routes a locally received PUP to the proper destination host.
        /// </summary>
        /// <param name="pup"></param>
        public void RouteIncomingLocalPacket(PUP pup, bool route)
        {
            //
            // Check the network -- if it specifies network zero (coming from a host that doesn't yet know what
            // network it's on, or specifying the current network) or our network
            // we will pass it on to the protocol suite.
            //
            if (pup.DestinationPort.Network == 0 || pup.DestinationPort.Network == DirectoryServices.Instance.LocalHostAddress.Network)
            {
                Log.Write(LogType.Verbose, LogComponent.PUP, "Routing incoming packet.");

                _localProtocolDispatcher.ReceivePUP(pup);
            }
            else if (route)
            {
                //
                // Not for our network -- see if we know where to route it.
                //
                RoutePacketExternally(pup);
            }
            else
            {
                //
                // Not local, and we were asked not to route this PUP, so drop it on the floor.
                //
            }
        }
Ejemplo n.º 4
0
        private void RouteIncomingExternalPacket(PUP p)
        {
            //
            // Ensure that this is for our network; otherwise this has been misrouted.
            // (Since we don't do multi-hop routing, any packet coming in through a gateway
            // interface must be destined for us.)
            //
            if (p.DestinationPort.Network == DirectoryServices.Instance.LocalNetwork)
            {
                //
                // Send it out on the local network for anyone to see.
                //
                _pupPacketInterface.Send(p);

                //
                // And if it's intended for us (the IFS server) let our services have a crack at it, too.
                //
                if (p.DestinationPort.Host == DirectoryServices.Instance.LocalHostAddress.Host ||       // us specifically
                    p.DestinationPort.Host == 0)                                                        // broadcast
                {
                    _localProtocolDispatcher.ReceivePUP(p);
                }
            }
            else
            {
                //
                // This was misrouted.  Log it and drop.
                //
                Log.Write(LogType.Error,
                          LogComponent.Routing,
                          "PUP was misrouted; intended for network {0}, host {1}",
                          p.DestinationPort.Network,
                          p.DestinationPort.Host);
            }
        }
Ejemplo n.º 5
0
        public void Send(PUP p)
        {
            //
            // Write PUP to UDP:
            //
            // For now, no actual routing (Gateway not implemented yet), everything is on the same 'net.
            // Just send a broadcast UDP with the encapsulated frame inside of it.
            //

            // Build the outgoing data; this is:
            // 1st word: length of data following
            // 2nd word: 3mbit destination / source bytes
            // 3rd word: frame type (PUP)
            byte[] encapsulatedFrame = new byte[6 + p.RawData.Length];

            // 3mbit Packet length
            encapsulatedFrame[0] = (byte)((p.RawData.Length / 2 + 2) >> 8);
            encapsulatedFrame[1] = (byte)(p.RawData.Length / 2 + 2);

            // addressing
            encapsulatedFrame[2] = p.DestinationPort.Host;
            encapsulatedFrame[3] = p.SourcePort.Host;

            // frame type
            encapsulatedFrame[4] = (byte)(_pupFrameType >> 8);
            encapsulatedFrame[5] = (byte)_pupFrameType;

            // Actual data
            p.RawData.CopyTo(encapsulatedFrame, 6);

            // Send as UDP broadcast.
            _udpClient.Send(encapsulatedFrame, encapsulatedFrame.Length, _broadcastEndpoint);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Pings the client with an empty AData PUP, which will cause it to respond with an ACK containing client BSP information.
        /// </summary>
        private void RequestClientStats()
        {
            //
            // Send an empty AData PUP to keep the connection alive and to update the client data stats.
            //
            PUP aData = new PUP(PupType.AData, _sendPos, _clientConnectionPort, _serverConnectionPort, new byte[0]);

            Router.Instance.SendPup(aData);
        }
Ejemplo n.º 7
0
 /// <summary>
 /// Finds the appropriate channel for the given PUP.
 /// </summary>
 /// <param name="p"></param>
 /// <returns></returns>
 private static BSPChannel FindChannelForPup(PUP p)
 {
     if (_activeChannels.ContainsKey(p.DestinationPort.Socket))
     {
         return(_activeChannels[p.DestinationPort.Socket]);
     }
     else
     {
         return(null);
     }
 }
Ejemplo n.º 8
0
        /// <summary>
        /// Sends a Mark (or AMark) to the client.
        /// </summary>
        /// <param name="markType"></param>
        /// <param name="ack"></param>
        public void SendMark(byte markType, bool ack)
        {
            if (_destroyed)
            {
                return;
            }

            PUP markPup = new PUP(ack ? PupType.AMark : PupType.Mark, _sendPos, _clientConnectionPort, _serverConnectionPort, new byte[] { markType });

            // Send it.
            SendDataPup(markPup);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Handles an End request from the client.
        /// </summary>
        /// <param name="p"></param>
        public void End(PUP p)
        {
            PUP endReplyPup = new PUP(PupType.EndReply, p.ID, _clientConnectionPort, _serverConnectionPort, new byte[0]);

            Router.Instance.SendPup(endReplyPup);

            // "The receiver of the End PUP responds by returning an EndReply Pup with matching ID and then
            //  _dallying_ up to some reasonably long timeout interval (say, 10 seconds) in order to respond to
            // a retransmitted End Pup should its initial EndReply be lost.  If and when the dallying end of the
            // stream connection receives its EndReply, it may immediately self destruct."
            // TODO: actually make this happen...
        }
Ejemplo n.º 10
0
        private void ReceiveCallback(Packet p)
        {
            //
            // Filter out encapsulated 3mbit frames and look for PUPs, forward them on.
            //

            if ((int)p.Ethernet.EtherType == _3mbitFrameType)
            {
                Log.Write(LogType.Verbose, LogComponent.Ethernet, "3mbit pup received.");

                MemoryStream packetStream = p.Ethernet.Payload.ToMemoryStream();

                // Read the length prefix (in words), convert to bytes.
                // Subtract off 2 words for the ethernet header
                int length = ((packetStream.ReadByte() << 8) | (packetStream.ReadByte())) * 2 - 4;

                // Read the address (1st word of 3mbit packet)
                byte destination = (byte)packetStream.ReadByte();
                byte source      = (byte)packetStream.ReadByte();

                // Read the type and switch on it
                int etherType3mbit = ((packetStream.ReadByte() << 8) | (packetStream.ReadByte()));

                //
                // Ensure this is a packet we're interested in.
                //
                if (etherType3mbit == _pupFrameType &&                          // it's a PUP
                    (destination == DirectoryServices.Instance.LocalHost ||     // for us, or...
                     destination == 0))                                         // broadcast
                {
                    try
                    {
                        PUP pup = new PUP(packetStream, length);
                        _routerCallback(pup, destination != 0);
                    }
                    catch (Exception e)
                    {
                        // An error occurred, log it.
                        Log.Write(LogType.Error, LogComponent.PUP, "Error handling PUP: {0} {1}\n\n{2}", e.Message, e.StackTrace, e.InnerException);
                    }
                }
                else
                {
                    Log.Write(LogType.Warning, LogComponent.Ethernet, "3mbit packet is not a PUP, dropping");
                }
            }
            else
            {
                // Not a PUP, Discard the packet.  We will not log this, so as to keep noise down.
                //Log.Write(LogLevel.DroppedPacket, "Not a PUP.  Dropping.");
            }
        }
Ejemplo n.º 11
0
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!PUP.IsMode("e"))
        {
            PUP.IncludeJQuery = true;
        }
        if (!PUP.IsMode("aep"))
        {
            //StyleOverridePH.Controls.Add(new LiteralControl("<style type='text/css'>body {background-position: center top; background-image: url(/dreamstudio/images/bkgd/DarkSkyBkgd.jpg); text-align:center; margin:0 auto;}</style>"));
            StyleOverridePH.Controls.Add(new LiteralControl("<style type='text/css'>#MasterAll{background:#fff;height:auto;width:100%;min-width:750px;max-width:950px;text-align:left;margin: 0 auto;}</style>"));
            StyleOverridePH.Controls.Add(new LiteralControl("<style type='text/css'>#ContentArea{margin-left: 24px; margin-right: 20px;}</style>"));
        }
        else
        {
            //TopNavigationPanel.Visible = false;
            SearchPanel.Visible = false;
        }
        if (PUP.IsMode("a"))
        {
            StyleOverridePH.Controls.Add(new LiteralControl("<style type='text/css'>body {text-align:left; margin:0 auto;}</style>"));
            StyleOverridePH.Controls.Add(new LiteralControl("<style type='text/css'>#ContentArea{margin-left: 0px; margin-right: 0px;}</style>"));
            StyleOverridePH.Controls.Add(new LiteralControl("<style type='text/css'>.contentArea{margin-left: 0px; margin-right: 0px;}</style>"));
            StyleOverridePH.Controls.Add(new LiteralControl("<style type='text/css'>#MasterAll{background:#fff;height:auto;width:100%;min-width:180px;max-width:950px;text-align:left;margin: 0 auto;}</style>"));
        }
        if (PUP.IsMode("ae"))
        {
            StyleOverridePH.Controls.Add(new LiteralControl("<style type='text/css'>body {line-height: 1em; } .contentBox { margin-top: 80px; } .masterMessageArea { background-color:#fff; }</style>"));
            SearchPanel.Visible = false;
            //FooterPanel.Visible = false;
        }
        if (PUP.IsMode("ae"))
        {
            HeaderPanel.Visible = false;
        }
        //HomeHL.NavigateUrl = PUP.GetLink("/core/item/page.aspx", 56809);
        //ArtworkHL.NavigateUrl = PUP.GetLink("/core/item/page.aspx", 56810);
        //AboutHL.NavigateUrl = PUP.GetLink("/core/item/page.aspx", 56819);
        //ContactHL.NavigateUrl = PUP.GetLink("/core/item/page.aspx", 56820);

        if (PUP.IContains(PUP.Host, "dynamicspd.com"))
        {
            CopyrightHL.NavigateUrl = "http://DynamicsPD.com";
            CopyrightHL.Text        = "&copy; " + DateTime.Now.Year.ToString() + " Patrol Dynamics - Community Policing System";
        }
        else if (PUP.ItemID != 94009) // The Old Explorer
        {
            CopyrightHL.NavigateUrl = "http://DreamStudio.com";
            CopyrightHL.Text        = "&copy; " + DateTime.Now.Year.ToString() + " dreamstudio";
        }
        CopyrightHL.CssClass = "tinytext";
    }
Ejemplo n.º 12
0
        private void RoutePacketExternally(PUP p)
        {
            RoutingTableEntry destinationNetworkEntry = _routingTable.GetAddressForNetworkNumber(p.DestinationPort.Network);

            if (destinationNetworkEntry != null)
            {
                //
                // Send this out through the external network interface.
                //
                if (_gatewayUdpClient != null)
                {
                    Log.Write(LogType.Verbose,
                              LogComponent.Routing,
                              "-> PUP routed to {0}:{1}, type {2} source {3} destination {4}.",
                              destinationNetworkEntry.HostAddress,
                              destinationNetworkEntry.Port,
                              p.Type,
                              p.SourcePort,
                              p.DestinationPort);


                    try
                    {
                        _gatewayUdpClientLock.EnterWriteLock();
                        _gatewayUdpClient.Send(p.RawData, p.RawData.Length, destinationNetworkEntry.HostAddress, destinationNetworkEntry.Port);
                    }
                    catch (Exception e)
                    {
                        Log.Write(LogType.Error,
                                  LogComponent.Routing,
                                  "Gateway UDP client send failed, error {0}.  Continuing.",
                                  e.Message);
                    }
                    finally
                    {
                        _gatewayUdpClientLock.ExitWriteLock();
                    }
                }
            }
            else
            {
                //
                // We don't know where to send this, drop it instead.
                //
                Log.Write(
                    LogType.Verbose,
                    LogComponent.Routing,
                    "Outgoing PUP is for unknown network {0}, dropping.", p.DestinationPort.Network);
            }
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Sends an Abort PUP to the client, (generally indicating a catastrophic failure of some sort.)
        /// </summary>
        /// <param name="message"></param>
        public void SendAbort(string message)
        {
            if (_destroyed)
            {
                return;
            }

            PUP abortPup = new PUP(PupType.Abort, _startPos, _clientConnectionPort, _serverConnectionPort, Helpers.StringToArray(message));

            //
            // Send this directly, do not wait for the client to be ready (since it may be wedged, and we don't expect anyone to actually notice
            // this anyway).
            //
            Router.Instance.SendPup(abortPup);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Sends a PUP.  Will block if client is unable to receive data.  If timeouts expire, channel will be shut down.
        /// </summary>
        /// <param name="p"></param>
        private void SendDataPup(PUP p)
        {
            //
            // Sanity check:  This should only be called for Data or Mark pups.
            //
            if (p.Type != PupType.AData && p.Type != PupType.Data && p.Type != PupType.Mark && p.Type != PupType.AMark)
            {
                throw new InvalidOperationException("Invalid PUP type for SendDataPup.");
            }

            //
            // Add the pup to the output window.  This may block if the window is full.
            //
            AddPupToOutputWindow(p);
        }
Ejemplo n.º 15
0
        public void SendEnd()
        {
            PUP endPup = new PUP(PupType.EFTPEnd, _sendPos, _clientConnectionPort, _serverConnectionPort, new byte[0]);

            Router.Instance.SendPup(endPup);

            // Await an ack
            _outputAckEvent.WaitOne(EFTPAckTimeoutPeriod);

            _sendPos++;

            // Send another end to close things off.
            endPup = new PUP(PupType.EFTPEnd, _sendPos, _clientConnectionPort, _serverConnectionPort, new byte[0]);
            Router.Instance.SendPup(endPup);
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Sends an ACK to the client.
        /// </summary>
        private void SendAck()
        {
            _inputLock.EnterReadLock();
            BSPAck ack = new BSPAck();

            ack.MaxBytes  = MaxBytes;
            ack.MaxPups   = MaxPups;
            ack.BytesSent = MaxBytes;
            _inputLock.ExitReadLock();

            PUP ackPup = new PUP(PupType.Ack, _recvPos, _clientConnectionPort, _serverConnectionPort, Serializer.Serialize(ack));

            Router.Instance.SendPup(ackPup);

            Log.Write(LogType.Verbose, LogComponent.BSP, "ACK sent.");
        }
Ejemplo n.º 17
0
        public void Send(PUP p)
        {
            //
            // Write PUP to ethernet:
            //

            // Build the outgoing data; this is:
            // 1st word: length of data following
            // 2nd word: 3mbit destination / source bytes
            // 3rd word: frame type (PUP)
            byte[] encapsulatedFrame = new byte[6 + p.RawData.Length];

            // 3mbit Packet length
            encapsulatedFrame[0] = (byte)((p.RawData.Length / 2 + 2) >> 8);
            encapsulatedFrame[1] = (byte)(p.RawData.Length / 2 + 2);

            // addressing
            encapsulatedFrame[2] = p.DestinationPort.Host;
            encapsulatedFrame[3] = p.SourcePort.Host;

            // frame type
            encapsulatedFrame[4] = (byte)(_pupFrameType >> 8);
            encapsulatedFrame[5] = (byte)_pupFrameType;

            // Actual data
            p.RawData.CopyTo(encapsulatedFrame, 6);

            MacAddress destinationMac = new MacAddress(_10mbitBroadcast);

            // Build the outgoing packet; place the source/dest addresses, type field and the PUP data.
            EthernetLayer ethernetLayer = new EthernetLayer
            {
                Source      = _interface.GetMacAddress(),
                Destination = destinationMac,
                EtherType   = (EthernetType)_3mbitFrameType,
            };

            PayloadLayer payloadLayer = new PayloadLayer
            {
                Data = new Datagram(encapsulatedFrame),
            };

            PacketBuilder builder = new PacketBuilder(ethernetLayer, payloadLayer);

            // Send it over the 'net!
            _communicator.SendPacket(builder.Build(DateTime.Now));
        }
Ejemplo n.º 18
0
        public BSPChannel(PUP rfcPup, UInt32 socketID)
        {
            _inputLock  = new ReaderWriterLockSlim();
            _outputLock = new ReaderWriterLockSlim();

            _inputWriteEvent = new AutoResetEvent(false);
            _inputQueue      = new Queue <ushort>(65536);

            _outputAckEvent   = new AutoResetEvent(false);
            _outputReadyEvent = new AutoResetEvent(false);
            _dataReadyEvent   = new AutoResetEvent(false);
            _outputQueue      = new Queue <byte>(65536);

            _outputWindow     = new List <PUP>(16);
            _outputWindowLock = new ReaderWriterLockSlim();

            _destroyed = false;

            // Init IDs, etc. based on RFC PUP
            _lastClientRecvPos = _startPos = _recvPos = _sendPos = rfcPup.ID;

            // Set up socket addresses.
            // The client sends the connection port it prefers to use
            // in the RFC pup.
            _clientConnectionPort = new PUPPort(rfcPup.Contents, 0);

            _originalDestinationPort = rfcPup.DestinationPort;

            // If the client doesn't know what network it's on, it's now on ours.
            if (_clientConnectionPort.Network == 0)
            {
                _clientConnectionPort.Network = DirectoryServices.Instance.LocalNetwork;
            }

            // We create our connection port using a unique socket address.
            _serverConnectionPort = new PUPPort(DirectoryServices.Instance.LocalHostAddress, socketID);

            //
            // Init MaxPups to indicate that we need to find out what the client actually supports when we first
            // start sending data.
            //
            _clientLimits.MaxPups = 0xffff;

            // Create our consumer thread for output and kick it off.
            _consumerThread = new Thread(OutputConsumerThread);
            _consumerThread.Start();
        }
Ejemplo n.º 19
0
        public void RecvAck(PUP p)
        {
            //
            // Sanity check that the client's position matches ours.
            //
            _lastRecvPos = p.ID;
            if (_lastRecvPos != _sendPos)
            {
                Log.Write(LogType.Error, LogComponent.EFTP, "Client position does not match server ({0} != {1}",
                          _lastRecvPos, _sendPos);
            }

            //
            // Unblock those waiting for an ACK.
            //
            _outputAckEvent.Set();
        }
Ejemplo n.º 20
0
        private void GatewayInformationWorker()
        {
            uint infoPupID = (uint)(new Random().Next());

            while (true)
            {
                //
                // From gatewayinformation.press:
                // "Each gateway host must also periodically broadcast Gateway Information Pups, as described above,
                // on all directly-connected networks.  The frequency of this broadcast should be approximately one
                // every 30 seconds, and immediately whenever the gateway’s own routing table changes (see below).
                // These Pups should be sent from socket 2 to socket 2."
                //
                // At this time, we don't do anything with gateway information PUPs that we receive -- they could
                // at some point be used as originally intended, to dynamically update routing tables, but it would
                // require some serious security investments to make sure that the tables don't get poisoned.
                // However, even though we don't use them, some Alto software does.  For example, the PUP libraries
                // used by Mazewar expect to get periodic updates or eventually it will assume the route is no longer
                // viable and drop connections.
                //

                // Delay 30 seconds
                Thread.Sleep(30000);

                byte[] infoArray = GetGatewayInformationArray();

                // From us, on socket 2
                PUPPort localPort = new PUPPort(DirectoryServices.Instance.LocalHostAddress, 2);

                //
                // The set of known networks is by default the set of directly-connected networks.
                //
                byte[] knownNetworks = Router.Instance.RoutingTable.GetKnownNetworks();

                foreach (byte network in knownNetworks)
                {
                    // Send a broadcast to the specified network
                    PUPPort remotePort = new PUPPort(network, 0, 2);

                    PUP infoPup = new PUP(PupType.GatewayInformationResponse, infoPupID++, remotePort, localPort, infoArray);
                    Router.Instance.SendPup(infoPup);

                    Log.Write(LogComponent.MiscServices, "Gateway Information packet sent to network {0}", network);
                }
            }
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Called by dispatcher to send incoming data destined for this protocol
        /// </summary>
        /// <param name="p"></param>
        public override void RecvData(PUP p)
        {
            switch (p.Type)
            {
            case PupType.GatewayInformationRequest:
                SendGatewayInformationResponse(p);
                break;

            case PupType.GatewayInformationResponse:
                // Currently a no-op.
                Log.Write(LogComponent.MiscServices, String.Format("Gateway Information handler unimplemented."));
                break;

            default:
                Log.Write(LogComponent.MiscServices, String.Format("Unhandled Gateway protocol {0} ({1})", p.Type, (int)p.Type));
                break;
            }
        }
Ejemplo n.º 22
0
    protected void Page_Load(object sender, EventArgs e)
    {
        SiteID = PUP.SiteID;
        //T = PUP.WrapID + "." + PUP.SiteID; // Wrap and SiteID
        if (PUP.IContains(PUP.Host, "localhost") || PUP.IContains(PUP.Host, "review."))
        {
            T += "?db=system";
        }
        //TitleLT.Text = PUP.SiteTitle.ToUpper();
        FooterLiteral.Text = GetFooterLinks("");
        AllMenu();

        if (PUP.IsMode("aep"))
        {
            NavPanel.Visible    = false;
            FooterPanel.Visible = false;
        }
    }
Ejemplo n.º 23
0
        /// <summary>
        /// Invoked when the client sends an ACK.
        /// Update our record of the client's PUP buffers.
        /// </summary>
        /// <param name="ackPUP"></param>
        public void RecvAck(PUP ackPUP)
        {
            //_outputWindowLock.EnterWriteLock();
            _clientLimits = (BSPAck)Serializer.Deserialize(ackPUP.Contents, typeof(BSPAck));

            Log.Write(LogType.Verbose, LogComponent.BSP,
                      "ACK from client: bytes sent {0}, max bytes {1}, max pups {2}",
                      _clientLimits.BytesSent,
                      _clientLimits.MaxBytes,
                      _clientLimits.MaxPups);

            _lastClientRecvPos = ackPUP.ID;

            //
            // Unblock those waiting for an ACK.
            //
            _outputAckEvent.Set();
        }
Ejemplo n.º 24
0
        public static void RecvData(PUP p)
        {
            EFTPChannel channel = FindChannelForPup(p);

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

            switch (p.Type)
            {
            case PupType.EFTPData:
            {
                channel.RecvData(p);
            }
            break;

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

            case PupType.EFTPEnd:
            {
                channel.End(p);
            }
            break;

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

                DestroyChannel(channel);
            }
            break;

            default:
                throw new NotImplementedException(String.Format("Unhandled EFTP PUP type {0}.", p.Type));
            }
        }
Ejemplo n.º 25
0
Archivo: UDP.cs Proyecto: shirriff/IFS
        private void Receive(MemoryStream packetStream)
        {
            //
            // Look for PUPs, forward them on.
            //

            // Read the length prefix (in words), convert to bytes.
            // Subtract off 2 words for the ethernet header
            int length = ((packetStream.ReadByte() << 8) | (packetStream.ReadByte())) * 2 - 4;

            // Read the address (1st word of 3mbit packet)
            byte destination = (byte)packetStream.ReadByte();
            byte source      = (byte)packetStream.ReadByte();

            // Read the type and switch on it
            int etherType3mbit = ((packetStream.ReadByte() << 8) | (packetStream.ReadByte()));

            //
            // Ensure this is a packet we're interested in.
            //
            if (etherType3mbit == _pupFrameType &&                              // it's a PUP
                (destination == DirectoryServices.Instance.LocalHost ||         // for us, or...
                 destination == 0))                                             // broadcast
            {
                try
                {
                    Log.Write(LogType.Normal, LogComponent.UDP, "UDP receive");

                    PUP pup = new PUP(packetStream, length);
                    _routerCallback(pup, destination != 0);
                }
                catch (Exception e)
                {
                    // An error occurred, log it.
                    Log.Write(LogType.Error, LogComponent.PUP, "UDP Error handling PUP: {0} {1} {2}", e.Message, e.StackTrace, e.InnerException);
                }
            }
            else
            {
                Log.Write(LogType.Warning, LogComponent.Ethernet, "UDP packet is not a PUP, dropping");
            }
        }
Ejemplo n.º 26
0
        /// <summary>
        /// Adds the specified data/mark PUP to the moving output window, these PUPs will be picked up by the Output Thread
        /// and sent when the client is ready for them.
        /// </summary>
        /// <param name="p"></param>
        private void AddPupToOutputWindow(PUP p)
        {
            // Ensure things are set up
            EstablishWindow();

            _outputWindowLock.EnterUpgradeableReadLock();

            if (_outputWindow.Count < _clientLimits.MaxPups)
            {
                //
                // There's space in the window, so go for it.
                //
                _outputWindowLock.EnterWriteLock();
                _outputWindow.Add(p);
                _outputWindowLock.ExitWriteLock();
            }
            else
            {
                //
                // No space right now -- wait until the consumer has made some space.
                //
                // Leave the lock so the consumer is unblocked
                _outputWindowLock.ExitUpgradeableReadLock();

                _outputReadyEvent.WaitOne();

                // Re-enter.
                _outputWindowLock.EnterUpgradeableReadLock();

                _outputWindowLock.EnterWriteLock();
                _outputWindow.Add(p);
                _outputWindowLock.ExitWriteLock();
            }

            //
            // Tell the Consumer thread we've added a new PUP to be consumed.
            //
            _dataReadyEvent.Set();

            _outputWindowLock.ExitUpgradeableReadLock();
        }
Ejemplo n.º 27
0
        public bool AddPersonaje(Personaje personaje, int idUser, int idPartida)
        {
            var per = _personaje.AddPersonaje(personaje);
            PUP pup = new PUP();
            PersonajesCapacidades personajesCapacidades = new PersonajesCapacidades();

            pup.PersonajeId = per.PersonajeId;
            pup.UserId      = idUser;
            pup.PartidaId   = idPartida;
            var classCharacterCpacidades = _classCharacterCpacidadesData.GetClassCharacterCapacidades(per.ClassCharacterId.GetValueOrDefault());

            foreach (var clases in classCharacterCpacidades)
            {
                personajesCapacidades.CapacidadId = clases.CapacidadId;
                personajesCapacidades.PersonajeId = per.PersonajeId;
                personajesCapacidades.Nivel       = 1;
                _personajesCapacidadesData.AddPersonajesCapacidades(personajesCapacidades);
            }
            _pupdata.Add(pup);
            return(true);
        }
Ejemplo n.º 28
0
 /// <summary>
 /// Routes a PUP out to the world.
 /// </summary>
 /// <param name="p"></param>
 private void RouteOutgoingPacket(PUP p)
 {
     //
     // Check the destination network.  If it's 0 (meaning the sender doesn't know
     // what network it's on, or wants it to go out to whatever network it's currently
     // connected to) or it's destined for our network, we send it out directly through
     // the local network interface.
     //
     if (p.DestinationPort.Network == 0 ||
         p.DestinationPort.Network == DirectoryServices.Instance.LocalNetwork)
     {
         _pupPacketInterface.Send(p);
     }
     else
     {
         //
         // Not for our network -- see if we know what network this is going to.
         //
         RoutePacketExternally(p);
     }
 }
Ejemplo n.º 29
0
        /// <summary>
        /// Sends data to the channel (i.e. to the client).  Will block (waiting for an ACK) if an ACK is requested.
        /// </summary>
        /// <param name="data">The data to be sent</param>
        /// <param name="flush">Whether to flush data out immediately or to wait for enough for a full PUP first.</param>
        public void Send(byte[] data, int length, bool flush)
        {
            if (length > data.Length)
            {
                throw new InvalidOperationException("Length must be less than or equal to the size of data.");
            }

            if (_destroyed)
            {
                return;
            }

            // Add output data to output queue.
            // Again, this is really inefficient
            for (int i = 0; i < length; i++)
            {
                _outputQueue.Enqueue(data[i]);
            }

            if (flush || _outputQueue.Count >= PUP.MAX_PUP_SIZE)
            {
                // Send data until all is used (for a flush) or until we have less than a full PUP (non-flush).
                while (_outputQueue.Count >= (flush ? 1 : PUP.MAX_PUP_SIZE))
                {
                    byte[] chunk = new byte[Math.Min(PUP.MAX_PUP_SIZE, _outputQueue.Count)];

                    // Ugh.
                    for (int i = 0; i < chunk.Length; i++)
                    {
                        chunk[i] = _outputQueue.Dequeue();
                    }

                    // Send the data.
                    PUP dataPup = new PUP(flush ? PupType.AData : PupType.Data, _sendPos, _clientConnectionPort, _serverConnectionPort, chunk);
                    SendDataPup(dataPup);
                }
            }
        }
Ejemplo n.º 30
0
        /// <summary>
        /// Worker thread for UDP packet receipt.
        /// </summary>
        private void GatewayReceiveThread()
        {
            // Just call Receive forever, that's it.  This will never return.
            // (probably need to make this more elegant so we can tear down the thread
            // properly.)
            Log.Write(LogComponent.Routing, "Gateway UDP Receiver thread started for port {0}.", _gatewayUdpPort);

            IPEndPoint groupEndPoint = new IPEndPoint(IPAddress.Any, Configuration.UDPPort);

            while (true)
            {
                byte[] data = null;
                try
                {
                    data = _gatewayUdpClient.Receive(ref groupEndPoint);
                }
                catch (Exception e)
                {
                    //
                    // This can happen on occasion for reasons I don't quite understand.
                    // We will log the failure and attempt to continue.
                    //
                    Log.Write(LogType.Error,
                              LogComponent.Routing,
                              "Gateway UDP client receive failed, error {0}.  Continuing.",
                              e.Message);

                    continue;
                }

                // 1) validate that the packet came in on the right port
                // 2) validate packet
                // 3) get a PUP out of it
                // 4) send to RouteIncomingPacket.
                // 5) do it again.
                if (groupEndPoint.Port == _gatewayUdpPort)
                {
                    if (data.Length < PUP.PUP_HEADER_SIZE + PUP.PUP_CHECKSUM_SIZE ||
                        data.Length > PUP.MAX_PUP_SIZE + PUP.PUP_HEADER_SIZE + PUP.PUP_CHECKSUM_SIZE)
                    {
                        Log.Write(LogType.Error, LogComponent.Routing, "External PUP has an invalid size ({0}).  Dropping.", data.Length);
                        continue;
                    }

                    try
                    {
                        //
                        // See if we can get a PUP out of this.
                        //
                        PUP externalPUP = new PUP(new MemoryStream(data), data.Length);

                        //
                        // TODO: should technically bump the PUP's TransportControl field up;
                        // really need to rewrite the PUP class to make this possible without
                        // building up an entirely new PUP.
                        //
                        RouteIncomingExternalPacket(externalPUP);

                        Log.Write(LogType.Verbose,
                                  LogComponent.Routing,
                                  "<- External PUP received from {0}:{1}, type {2} source {3} destination {4}.  Routing to local network.",
                                  groupEndPoint.Address,
                                  groupEndPoint.Port,
                                  externalPUP.Type,
                                  externalPUP.SourcePort,
                                  externalPUP.DestinationPort);
                    }
                    catch (Exception e)
                    {
                        Log.Write(LogType.Error, LogComponent.Routing, "Error handling external PUP: {0}", e.Message);
                    }
                }
                else
                {
                    Log.Write(LogType.Verbose,
                              LogComponent.Routing,
                              "Packet from {0} received on wrong port ({1}), expected {2}.",
                              groupEndPoint.Address,
                              groupEndPoint.Port,
                              _gatewayUdpPort);
                }
            }
        }