<commit_before>/*
 * Copyright (c) Contributors, http://opensimulator.org/
 * See CONTRIBUTORS.TXT for a full list of copyright holders.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the OpenSim Project nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using OpenMetaverse.Packets;
using log4net;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Framework.Communications.Cache;
using OpenSim.Region.Environment.Scenes;

namespace OpenSim.Region.ClientStack.LindenUDP
{
    /// <summary>
    /// This class handles the initial UDP circuit setup with a client and passes on subsequent packets to the LLPacketServer
    /// </summary>
    public class LLUDPServer : ILLClientStackNetworkHandler, IClientNetworkServer
    {
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        /// <value>
        /// The client circuits established with this UDP server.  If a client exists here we can also assume that
        /// it is populated in clientCircuits_reverse and proxyCircuits (if relevant)
        /// </value>
        protected Dictionary<EndPoint, uint> clientCircuits = new Dictionary<EndPoint, uint>();
        public Hashtable clientCircuits_reverse = Hashtable.Synchronized(new Hashtable());
        protected Dictionary<uint, EndPoint> proxyCircuits = new Dictionary<uint, EndPoint>();
        
        private Socket m_socket;
        protected IPEndPoint ServerIncoming;
        protected byte[] RecvBuffer = new byte[4096];
        protected byte[] ZeroBuffer = new byte[8192];

        /// <value>
        /// This is an endpoint that is reused where we don't need to protect the information from potentially
        /// being stomped on by other threads.
        /// </value>
        protected EndPoint reusedEpSender = new IPEndPoint(IPAddress.Any, 0);
        
        protected int proxyPortOffset;
        
        protected AsyncCallback ReceivedData;
        protected LLPacketServer m_packetServer;
        protected Location m_location;

        protected uint listenPort;
        protected bool Allow_Alternate_Port;
        protected IPAddress listenIP = IPAddress.Parse("0.0.0.0");
        protected IScene m_localScene;
        protected AssetCache m_assetCache;

        /// <value>
        /// Manages authentication for agent circuits
        /// </value>
        protected AgentCircuitManager m_circuitManager;

        public IScene LocalScene
        {
            set
            {
                m_localScene = value;
                m_packetServer.LocalScene = m_localScene;
                m_location = new Location(m_localScene.RegionInfo.RegionHandle);
            }
        }

        public ulong RegionHandle
        {
            get { return m_location.RegionHandle; }
        }

        Socket IClientNetworkServer.Server
        {
            get { return m_socket; }
        }

        public bool HandlesRegion(Location x)
        {
            return x == m_location;
        }

        public void AddScene(Scene x)
        {
            LocalScene = x;
        }

        public void Start()
        {
            ServerListener();
        }

        public void Stop()
        {
            m_socket.Close();
        }

        public LLUDPServer()
        {
        }

        public LLUDPServer(
            IPAddress _listenIP, ref uint port, int proxyPortOffset, bool allow_alternate_port, IConfigSource configSource, 
            AssetCache assetCache, AgentCircuitManager authenticateClass)
        {
            Initialise(_listenIP, ref port, proxyPortOffset, allow_alternate_port, configSource, assetCache, authenticateClass);
        }

        /// <summary>
        /// Initialize the server
        /// </summary>
        /// <param name="_listenIP"></param>
        /// <param name="port"></param>
        /// <param name="proxyPortOffsetParm"></param>
        /// <param name="allow_alternate_port"></param>
        /// <param name="configSource"></param>
        /// <param name="assetCache"></param>
        /// <param name="circuitManager"></param>
        public void Initialise(
            IPAddress _listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource,
            AssetCache assetCache, AgentCircuitManager circuitManager)
        {
            ClientStackUserSettings userSettings = new ClientStackUserSettings();
            
            IConfig config = configSource.Configs["ClientStack.LindenUDP"];
            
            if (config != null)
            {
                if (config.Contains("client_throttle_multiplier"))
                    userSettings.ClientThrottleMultipler = config.GetFloat("client_throttle_multiplier"); 
            }   
            
            m_log.DebugFormat("[CLIENT]: client_throttle_multiplier = {0}", userSettings.ClientThrottleMultipler);
                
            proxyPortOffset = proxyPortOffsetParm;
            listenPort = (uint) (port + proxyPortOffsetParm);
            listenIP = _listenIP;
            Allow_Alternate_Port = allow_alternate_port;
            m_assetCache = assetCache;
            m_circuitManager = circuitManager;
            CreatePacketServer(userSettings);

            // Return new port
            // This because in Grid mode it is not really important what port the region listens to as long as it is correctly registered.
            // So the option allow_alternate_ports="true" was added to default.xml
            port = (uint)(listenPort - proxyPortOffsetParm);
        }

        protected virtual void CreatePacketServer(ClientStackUserSettings userSettings)
        {
            new LLPacketServer(this, userSettings);
        }

        /// <summary>
        /// This method is called every time that we receive new UDP data. 
        /// </summary>
        /// <param name="result"></param>
        protected virtual void OnReceivedData(IAsyncResult result)
        {
            Packet packet = null;
            int numBytes = 1;
            EndPoint epSender = new IPEndPoint(IPAddress.Any, 0);

            if (EndReceive(out numBytes, result, ref epSender))
            {
                // Make sure we are getting zeroes when running off the
                // end of grab / degrab packets from old clients
                //
                int z;
                for (z = numBytes ; z < RecvBuffer.Length ; z++)
                    RecvBuffer[z] = 0;

                int packetEnd = numBytes - 1;<commit_msg>If the proxy is on, we need to ignore the extra 6 bytes in the packet.<commit_after>/*
 * Copyright (c) Contributors, http://opensimulator.org/
 * See CONTRIBUTORS.TXT for a full list of copyright holders.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the OpenSim Project nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using OpenMetaverse.Packets;
using log4net;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Framework.Communications.Cache;
using OpenSim.Region.Environment.Scenes;

namespace OpenSim.Region.ClientStack.LindenUDP
{
    /// <summary>
    /// This class handles the initial UDP circuit setup with a client and passes on subsequent packets to the LLPacketServer
    /// </summary>
    public class LLUDPServer : ILLClientStackNetworkHandler, IClientNetworkServer
    {
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        /// <value>
        /// The client circuits established with this UDP server.  If a client exists here we can also assume that
        /// it is populated in clientCircuits_reverse and proxyCircuits (if relevant)
        /// </value>
        protected Dictionary<EndPoint, uint> clientCircuits = new Dictionary<EndPoint, uint>();
        public Hashtable clientCircuits_reverse = Hashtable.Synchronized(new Hashtable());
        protected Dictionary<uint, EndPoint> proxyCircuits = new Dictionary<uint, EndPoint>();
        
        private Socket m_socket;
        protected IPEndPoint ServerIncoming;
        protected byte[] RecvBuffer = new byte[4096];
        protected byte[] ZeroBuffer = new byte[8192];

        /// <value>
        /// This is an endpoint that is reused where we don't need to protect the information from potentially
        /// being stomped on by other threads.
        /// </value>
        protected EndPoint reusedEpSender = new IPEndPoint(IPAddress.Any, 0);
        
        protected int proxyPortOffset;
        
        protected AsyncCallback ReceivedData;
        protected LLPacketServer m_packetServer;
        protected Location m_location;

        protected uint listenPort;
        protected bool Allow_Alternate_Port;
        protected IPAddress listenIP = IPAddress.Parse("0.0.0.0");
        protected IScene m_localScene;
        protected AssetCache m_assetCache;

        /// <value>
        /// Manages authentication for agent circuits
        /// </value>
        protected AgentCircuitManager m_circuitManager;

        public IScene LocalScene
        {
            set
            {
                m_localScene = value;
                m_packetServer.LocalScene = m_localScene;
                m_location = new Location(m_localScene.RegionInfo.RegionHandle);
            }
        }

        public ulong RegionHandle
        {
            get { return m_location.RegionHandle; }
        }

        Socket IClientNetworkServer.Server
        {
            get { return m_socket; }
        }

        public bool HandlesRegion(Location x)
        {
            return x == m_location;
        }

        public void AddScene(Scene x)
        {
            LocalScene = x;
        }

        public void Start()
        {
            ServerListener();
        }

        public void Stop()
        {
            m_socket.Close();
        }

        public LLUDPServer()
        {
        }

        public LLUDPServer(
            IPAddress _listenIP, ref uint port, int proxyPortOffset, bool allow_alternate_port, IConfigSource configSource, 
            AssetCache assetCache, AgentCircuitManager authenticateClass)
        {
            Initialise(_listenIP, ref port, proxyPortOffset, allow_alternate_port, configSource, assetCache, authenticateClass);
        }

        /// <summary>
        /// Initialize the server
        /// </summary>
        /// <param name="_listenIP"></param>
        /// <param name="port"></param>
        /// <param name="proxyPortOffsetParm"></param>
        /// <param name="allow_alternate_port"></param>
        /// <param name="configSource"></param>
        /// <param name="assetCache"></param>
        /// <param name="circuitManager"></param>
        public void Initialise(
            IPAddress _listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource,
            AssetCache assetCache, AgentCircuitManager circuitManager)
        {
            ClientStackUserSettings userSettings = new ClientStackUserSettings();
            
            IConfig config = configSource.Configs["ClientStack.LindenUDP"];
            
            if (config != null)
            {
                if (config.Contains("client_throttle_multiplier"))
                    userSettings.ClientThrottleMultipler = config.GetFloat("client_throttle_multiplier"); 
            }   
            
            m_log.DebugFormat("[CLIENT]: client_throttle_multiplier = {0}", userSettings.ClientThrottleMultipler);
                
            proxyPortOffset = proxyPortOffsetParm;
            listenPort = (uint) (port + proxyPortOffsetParm);
            listenIP = _listenIP;
            Allow_Alternate_Port = allow_alternate_port;
            m_assetCache = assetCache;
            m_circuitManager = circuitManager;
            CreatePacketServer(userSettings);

            // Return new port
            // This because in Grid mode it is not really important what port the region listens to as long as it is correctly registered.
            // So the option allow_alternate_ports="true" was added to default.xml
            port = (uint)(listenPort - proxyPortOffsetParm);
        }

        protected virtual void CreatePacketServer(ClientStackUserSettings userSettings)
        {
            new LLPacketServer(this, userSettings);
        }

        /// <summary>
        /// This method is called every time that we receive new UDP data. 
        /// </summary>
        /// <param name="result"></param>
        protected virtual void OnReceivedData(IAsyncResult result)
        {
            Packet packet = null;
            int numBytes = 1;
            EndPoint epSender = new IPEndPoint(IPAddress.Any, 0);

            if (EndReceive(out numBytes, result, ref epSender))
            {
                // Make sure we are getting zeroes when running off the
                // end of grab / degrab packets from old clients
                //
                int z;
                for (z = numBytes ; z < RecvBuffer.Length ; z++)
                    RecvBuffer[z] = 0;

                int packetEnd = numBytes - 1;
                if (proxyPortOffset != 0) packetEnd -= 6;
{'fraction_non_alphanumeric': 0.07477271321664915, 'fraction_numerical': 0.0025357164945265633, 'mean_word_length': 2.2726168791742563, 'pattern_counts': {'":': 0, '<': 69, '<?xml version=': 0, '>': 67, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '129925', 'n_tokens_mistral': 4112, 'n_tokens_neox': 3886, 'n_words': 1353}