INET RED с реализацией алгоритма маркировки ECN - PullRequest
0 голосов
/ 27 января 2020

У меня возникли проблемы с пониманием логики c, стоящей за алгоритмом тегирования ECN, реализованным в INET классе REDDropper. cc.

Насколько я знаю, RED AQM с включенным ECN должен маркировать битами CE (биты IP ToS, установленными в 0x11) каждый пакет, который в противном случае он отбрасывал (если биты IP ToS не установлены в 0x00, или аналогично исходный TCP не поддерживает ECN). Однако в реализации inet4 также рассматривается флаг markNext, назначение которого мне не понятно .....

Следующая функция возвращает true, если пакет может быть помещен в очередь, и false, если он должен быть сброшенным Если флаг useEcn равен true, а биты IP ToS НЕ установлены в 0x00 ( ecn! = IP_ECN_NOT_ECT , т. Е. Источник TCP поддерживает ECN), алгоритм RED должен пометить пакет, а не отбрасывать его ,

Однако этот код также выполняет некоторую логическую c переменную markNext . В чем смысл? Кажется, у маркера есть память о прошлом .. Спасибо !!

bool RedDropper::matchesPacket(Packet *packet)
{
    auto redResult = doRandomEarlyDetection(packet);
    switch (redResult) {
        case RANDOMLY_ABOVE_LIMIT:
        case ABOVE_MAX_LIMIT: {
            if (!useEcn)
                return false;
            else {
                IpEcnCode ecn = EcnMarker::getEcn(packet);
                if (ecn == IP_ECN_NOT_ECT)
                    return false;
                else {
                    // if next packet should be marked and it is not
                    if (markNext && ecn != IP_ECN_CE) {
                        EcnMarker::setEcn(packet, IP_ECN_CE);
                        markNext = false;
                    }
                    else {
                        if (ecn == IP_ECN_CE)
                            markNext = true;
                        else
                            EcnMarker::setEcn(packet, IP_ECN_CE);
                    }
                    return true;
                }
            }
        }
        case RANDOMLY_BELOW_LIMIT:
        case BELOW_MIN_LIMIT:
            return true;
        case QUEUE_FULL:
            return false;
        default:
            throw cRuntimeError("Unknown XXX");
    }
}
...