• Lunes 18 de Noviembre de 2024, 02:20

Autor Tema:  "Anti-flooding"  (Leído 1473 veces)

U2_Caparzo

  • Miembro activo
  • **
  • Mensajes: 45
  • Nacionalidad: cl
  • Super duper divertido xDD
    • Ver Perfil
"Anti-flooding"
« en: Miércoles 3 de Octubre de 2012, 04:30 »
0
bueno, hola a todos, pues tengo una duda, hice una clase para evitar el envio masivo de paquetes de datos a un servidor de una aplicacion que hago, ya que produciria retraso en la respuesta para los otros clientes, pasa que quiero saber si la clase que hice serviria en cierto modo para detener eso, tengo fe en que si, no lo he probado si funciona como deberia, pero me parece que si,  pasa que si lo probara en mi pc, el resultado seria optimo(creo yo), quiero saber si en realidad serviria frente a varios clientes verdaderos.


Código: [Seleccionar]
public class Entry
    {
        public DateTime lastTry;
        public IClient client;
        public Entry(IClient arg)
        {
            lastTry = DateTime.Now;
            client = arg;
        }
        public void Disconnect()
        {
            client.Disconnect();
        }
    }

    /// <summary>
    /// Clase usada para evitar el envio masivo de bytes desde los clientes que no
    /// sean el que se esta manipulando.
    ///
    /// </summary>
    public class Anti_Flooding
    {
        //Indica si el Anti-Flooding esta funcionando
        static bool IsWorking;

        //Medido en segundos, es la cantidad minima de segundos que debe esperar cada
        //cliente para enviar otro packet
        const int minConnectionSleep = 3;

        //Medido en minutos, es la cantidad de minutos que no se aceptaran conexiones
        //desde el cliente que este ban
        const int BannedTime = 5;
        static Thread BannedsRemover;
        /// <summary>
        /// IP vs Client
        /// </summary>
        static SafeDictionary<string, Entry> Entries = new SafeDictionary<string, Entry>();
        static SafeDictionary<string, Entry> Banneds = new SafeDictionary<string, Entry>();
       
        /// <summary>
        /// revisa si el IClient esta ban, en caso de estarlo lo desconecta y devuelve true
        /// </summary>
        /// <param name="arg">ICliente al que se le revisara Ban</param>
        /// <returns></returns>
        public static bool isBanned(IClient arg)
        {
            if (Banneds.ContainsKey(arg.IP))
            {
                arg.Disconnect();
                return true;
            }
            return false;
        }
        public static void Try(IClient arg)
        {
            if (!IsWorking)
                return;
            if (!Entries.ContainsKey(arg.IP))
            {
                Entry entry = new Entry(arg);
                Entries.Add(arg.IP, entry);
            }
            else
            {
                Entry entry = Entries[arg.IP];
                if (entry.lastTry.AddSeconds(minConnectionSleep) > DateTime.Now)
                {
                    entry.Disconnect();
                    Entries.Remove(arg.IP);
                    Banneds.Add(arg.IP, entry);
                }

            }
        }
        public static void StartAntiFlooding()
        {
            BannedsRemover = new Thread(new ThreadStart(RemoveBanneds));
            BannedsRemover.Start();
            IsWorking = true;
        }
        public static void StopAntiFlooding()
        {
            BannedsRemover.Abort();
            IsWorking = false;
            if (Banneds.Count > 0)
            {
                foreach (Entry entry in Banneds.Values)
                {
                    Entries.Add(entry.client.IP, entry);
                    Banneds.Remove(entry.client.IP);
                }
            }
        }
        static void RemoveBanneds()
        {
            while (true)
            {
                foreach (Entry entry in Banneds.Values)
                {
                    if (entry.lastTry.AddMinutes(BannedTime) <= DateTime.Now)
                    {
                        string IP = entry.client.IP;
                        Banneds.Remove(IP);
                        Entries.Add(IP, entry);
                    }
                }
                Thread.Sleep(20000);
            }
        }
    }

en caso de que si sirva y alguien lo quiera usar de verdad, deberan implementar en la clase que tienen como cliente la interfaz IClient

Código: [Seleccionar]
public interface IClient
    {
        void Disconnect();
        string IP { get; }
    }

la clase SafeDictionary es solo un simplificador de ConcurrentDictionary para que funcione como Dictionary y poder cambiarlo rapidamente en sources que descargaba con mas de un hilo/thread

Código: [Seleccionar]
public class SafeDictionary<TKey, TValue> : ConcurrentDictionary<TKey, TValue>
    {
        public bool Add(TKey Key, TValue value)
        {
            return base.TryAdd(Key, value);
        }
        public new TValue this[TKey key]
        {
            get
            {
                TValue value = default(TValue);
                base.TryGetValue(key, out value);
                return value;
            }
            set
            {
                base.TryUpdate(key, value, this[key]);
            }

        }
        public bool Remove(TKey key)
        {
            TValue value;
            return base.TryRemove(key, out value);
        }


de antemano gracias
Lo dificil se hace... lo imposible se intenta
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.(Frase de Albert Einstein)