Re[3]: Протокол на основе UDP
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 28.02.10 12:02
Оценка: +1
Здравствуйте, fk0, Вы писали:

T>>CRC даёт хорошую защиту от сбоев оборудования. От преднамеренного изменения пакетов "человеком-посередине" не защищает.


fk0> Жизненный опыт. CRC даёт хреновейшую защиту от "сбоев оборудования" при обрыве, когда с середины пакета и до конца все байты FFFF или 0000 не важно.


Прошу примера. Мне сложно себе представить, чтобы правильно вычисленная и уложенная CRC не замечатала такие ситуации.

fk0> А контрольная сумма замечательно работает. Кто-то всерьёз полагает, что бред повсеместно приведённый в некоторой литературе, что дескать CRC не используется в TCP/IP ровно потому, что его трудно считать? Нет, он тривиально считается в аппаратуре, побитно...


Вообще-то TCP/IP начинался в условиях отсутствия такой аппаратуры. Хотя причину не держать таблицу в 512 байт я слабо понимаю. Может влиять ещё скорость вычисления.
The God is real, unless declared integer.
Re[7]: Протокол на основе UDP
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 28.02.10 12:05
Оценка:
Здравствуйте, Pzz, Вы писали:

T>>Нет NAT для UDP, потому что нет сессии. Нет таймаутов. Почему вы продолжаете их придумывать?


Pzz>Для UDP есть NAT, причем обычнуе роутеры в среднем его поддерживают. Сессии как таковой нет, но роутер просто хранит в таблице в течении некоторого времени запись о том, что такой-то внутренний адрес:порт соответствует такому-то внешнему. Если в течении этого времени через такую ассоциацию траффика нет, ассоциация сгорает и освобождает место в таблице. Чтобы дырка в NAT'е не "заростала", достаточно посылать туда-обратно пакетик с некоторой периодичностью. Скажем, раз в минуту.


Pzz>Кстати, в случае TCP все то же самое. Роутер не может рассчитывать на то, что ваш компутер вежливо позакрывает все сессии. Иначе в случае выключения компутера записи в таблице NAT'а болтались бы до морковкина заговения. Просто в случае TCP роутер может, увидив закрытие соединения, выкинуть запись из таблице раньше, не дожидаясь таймаута.


Кстати. Есть ли реализации NAT, которые пытаются проверять живость соединения? Для TCP это могла бы быть посылка пакета без данных, просто с ACK. Для UDP мне нравится метод имени Sipura — на пакет из четырёх нулевых байт отвечается пустым пакетом.
The God is real, unless declared integer.
Re[4]: Протокол на основе UDP
От: Pzz Россия https://github.com/alexpevzner
Дата: 28.02.10 12:21
Оценка:
Здравствуйте, netch80, Вы писали:

fk0>> Жизненный опыт. CRC даёт хреновейшую защиту от "сбоев оборудования" при обрыве, когда с середины пакета и до конца все байты FFFF или 0000 не важно.


N>Прошу примера. Мне сложно себе представить, чтобы правильно вычисленная и уложенная CRC не замечатала такие ситуации.


IP'ная контрольная сумма не замечает вставления/удаления последовательности из четного количества нулей (насчет FF'ов не поручусь).
Re[4]: Протокол на основе UDP
От: fk0 Россия https://fk0.name
Дата: 28.02.10 13:38
Оценка:
Здравствуйте, netch80, Вы писали:

N>Здравствуйте, fk0, Вы писали:


T>>>CRC даёт хорошую защиту от сбоев оборудования. От преднамеренного изменения пакетов "человеком-посередине" не защищает.

fk0>> Жизненный опыт. CRC даёт хреновейшую защиту от "сбоев оборудования" при обрыве, когда с середины пакета и до конца все байты FFFF или 0000 не важно.
N>Прошу примера. Мне сложно себе представить, чтобы правильно вычисленная и уложенная CRC не замечатала такие ситуации.

Пример ниже. Прекрасно видно, что на случайных данных, на совершенно разных последовательностях (случайных), даже на коротких (несколко байт) пакетах можно нарваться на ситуацию, когда CRC совпадает, а хвост пакета (а то и весь пакет!) испорчен нулём или FF. Позапускай программу несколько раз (./a.out | less). Что характерно -- CRC должен быть равен заполняющему (всё портящему) байту. Так вот в реальном приборе, где проблемы были, там, догадайся...

Там CRC шёл в конце пакета

... и как следствие, портился "нужным" значением тоже.

Я для себя вывод сделал на всю жизнь. Ну кроме того, что долой самодельные протоколы... в данном случае протокол не самодельный. Нефиг CRC в конец закладывать или нужно иметь в концец чёткий маркер конца пакета. Да, длина там первым байтом в пакете ещё. CRC пакета с нулевой длиной -- правильно, ноль. Протокол, повторюсь, не самодельный, это проблема всего SMBUS (переименованный интелом I2C). И когда есть "обрывы" с заполнением конца FF-ами (характерная особенность I2C) и когда пакетов тысячи в секунду -- это проблема.

Да, конечно, 8-битный CRC надёжно защищает только от 8-и ошибочных битов подряд... 16-битный, соответственно, от 16-и. А там посылки короткие, по десятку байт, в протоколе 32 байта максимум. И что характерно, в такой ситуации 16-битовая сумма позволяет посылки короче 256 байт без ошибок...

#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>

/* compute CRC-8 for SMBUS (x^8 + x^2 + x + 1) */
uint_fast8_t crc_byte(uint_fast8_t byte, uint_fast8_t crc)
{
uint_fast8_t b;
        b=byte^crc;
        if (b&(1<<0)) crc^=0x7;
        if (b&(1<<1)) crc^=0xe;
        if (b&(1<<2)) crc^=0x1c;
        if (b&(1<<3)) crc^=0x38;
        if (b&(1<<4)) crc^=0x70;
        if (b&(1<<5)) crc^=0xe0;
        if (b&(1<<6)) crc^=0xc7;
        if (b&(1<<7)) crc^=0x89;
        return crc;
}

/* dump packet data in hex form */
void dump(const char *data, size_t size)
{
size_t n;
    for (n=0; n<size; n++) printf("%2.2X", (unsigned char)data[n]);
    fputc('\n', stdout);
}


int main (int ac, char *av[])
{
unsigned plen;      /* packet length */
char packet[256];    /* data */
char crc;        /* CRC of data with size plen */

unsigned n, fill, start;
char copy[256];
char ncrc;

    srand(time(NULL));

    /* run test for each packet length from 1 to 255 bytes inclusive */
    for (plen=1; plen<256; plen++) {

        /* print progress */
        fprintf(stderr, "\rlen=%2.2X", plen);
    
        /* fill packet with random bytes and compute CRC */
        crc=0;
        for (n=0; n<plen; n++) {
            packet[n]=rand()%0x100;
            crc=crc_byte(packet[n], crc);
        }

        /* fill packet tail (from 0 to plen inclusive) with 0/0xFF */
        for (fill=0; fill<0x100; fill+=0xff) {

            /* starting position */
            for (start=0; start<plen; start++)  {

                /* make copy and fill tail */
                memcpy(copy, packet, start);
                memset(&copy[start], fill, plen-start);

                /* compute CRC of damaged packet */
                ncrc=0;
                for (n=0; n<plen; n++)
                    ncrc=crc_byte(copy[n], crc);

                /* check if crc doesn't protect data integrity */
                if (crc != ncrc) continue;
                if (memcmp(copy, packet, plen)==0) continue;

                /* crc matches, but data is different */
                printf("length=%3u, tail=%3u, fill=%2.2X, crc=%2.2X\n",
                    plen, plen-start, fill, (unsigned char)crc);
                dump(packet, plen);
                dump(copy, plen);
                puts("--");

            }
        }
        
    }

    fputc('\n', stderr);
    return 0;
}



fk0>> А контрольная сумма замечательно работает. Кто-то всерьёз полагает, что бред повсеместно приведённый в некоторой литературе, что дескать CRC не используется в TCP/IP ровно потому, что его трудно считать? Нет, он тривиально считается в аппаратуре, побитно...

N>Вообще-то TCP/IP начинался в условиях отсутствия такой аппаратуры. Хотя причину не держать таблицу в 512 байт я слабо понимаю. Может влиять ещё скорость вычисления.

Вообще-то CRC считается и бестабличными методами достаточно быстро, если такая задача стоит. Опять же смотри пример. Все возражения "почему не 16-32 бита" -- потому что блоки не по 4 килобайта, а по десятку байт. А 16 бит принципиально ситуацию тут не изменит вообще.
Re[3]: Протокол на основе UDP
От: fk0 Россия https://fk0.name
Дата: 28.02.10 13:40
Оценка: +1
Здравствуйте, MikelSV, Вы писали:

fk0>> Бред в состоянии белой горячки.

MSV>Хмм, может быть. Я тут понял, что хочу через один порт гонять много отдельных потоков. Вот это действительно белая горячка, когда через 2 реальных соккета будут гоняться толпы виртуальных соединений.

Через 2 сокета можно поднять openvpn и гонять в ней чего угодно.

MSV>Простенькие вещи, типа пинга, возврата ip адреса и номера порта и возврата времени я приделал. они не требуют создания сессий и гоняются легко.


И ping с openvpn будет работать штатный и всё такое прочее.

"Как много весёлых ребят, и все делают велосипед..." (C)
Re[5]: Протокол на основе UDP
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 28.02.10 13:40
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Здравствуйте, netch80, Вы писали:


fk0>>> Жизненный опыт. CRC даёт хреновейшую защиту от "сбоев оборудования" при обрыве, когда с середины пакета и до конца все байты FFFF или 0000 не важно.


N>>Прошу примера. Мне сложно себе представить, чтобы правильно вычисленная и уложенная CRC не замечатала такие ситуации.


Pzz>IP'ная контрольная сумма не замечает вставления/удаления последовательности из четного количества нулей (насчет FF'ов не поручусь).


Стоп-стоп. Кирилл как раз говорит что CRC даёт слабую защиту (а контрольная сумма IP — достаточную). Ты приводишь пример на IP'шную сумму, хорошо. Но это как раз в противоречие его тезису. Я же хочу узнать, откуда такие странные выводы. То ли Кирилл оговорился и хотел сказать наоборот, то ли это противоречит тому, что я знал про эти средства.
The God is real, unless declared integer.
Re[5]: Протокол на основе UDP
От: fk0 Россия https://fk0.name
Дата: 28.02.10 13:43
Оценка:
Здравствуйте, Pzz, Вы писали:

fk0>>> Жизненный опыт. CRC даёт хреновейшую защиту от "сбоев оборудования" при обрыве, когда с середины пакета и до конца все байты FFFF или 0000 не важно.

N>>Прошу примера. Мне сложно себе представить, чтобы правильно вычисленная и уложенная CRC не замечатала такие ситуации.
Pzz>IP'ная контрольная сумма не замечает вставления/удаления последовательности из четного количества нулей (насчет FF'ов не поручусь).

Вставка, удаление (кроме как с конца) и перестановка -- что-то по физическим причинам маловероятное в последовательном протоколе. А вот "обрывы" с замещением данных на 0 или 1, или укорачивание пакета (удаление с конца), ну и просто искажение битов -- запросто.
Re[5]: Протокол на основе UDP
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 28.02.10 14:21
Оценка:
Здравствуйте, fk0, Вы писали:

fk0> Пример ниже. Прекрасно видно, что на случайных данных, на совершенно разных последовательностях (случайных), даже на коротких (несколко байт) пакетах можно нарваться на ситуацию, когда CRC совпадает, а хвост пакета (а то и весь пакет!) испорчен нулём или FF. Позапускай программу несколько раз (./a.out | less). Что характерно -- CRC должен быть равен заполняющему (всё портящему) байту. Так вот в реальном приборе, где проблемы были, там, догадайся...


Во-первых, с самого начала: твой пример попросту с багом. Если его исправить как следует:

$ diff -u m.c.00 m.c
--- m.c.orig
+++ m.c
@@ -67,7 +67,7 @@
                 /* compute CRC of damaged packet */
                 ncrc=0;
                 for (n=0; n<plen; n++)
-                    ncrc=crc_byte(copy[n], crc);
+                    ncrc=crc_byte(copy[n], ncrc);
 
                 /* check if crc doesn't protect data integrity */
                 if (crc != ncrc) continue;


то у меня получается в самом коротком случае 3 байта испорченных, иногда 4, обычно же оно не находит случаев короче чем 8 байт. Для CRC-8 это очень хороший результат. А твой пример умудряется находить даже последовательности с изменением одного последнего байта, что заведомо показывает на ошибочность твоего кода (собственно почему я и стал рыть).

Далее по частям программы:

fk0>/* compute CRC-8 for SMBUS (x^8 + x^2 + x + 1) */

fk0>uint_fast8_t crc_byte(uint_fast8_t byte, uint_fast8_t crc)
fk0>{
fk0>uint_fast8_t b;
fk0> b=byte^crc;
fk0> if (b&(1<<0)) crc^=0x7;
fk0> if (b&(1<<1)) crc^=0xe;
fk0> if (b&(1<<2)) crc^=0x1c;
fk0> if (b&(1<<3)) crc^=0x38;
fk0> if (b&(1<<4)) crc^=0x70;
fk0> if (b&(1<<5)) crc^=0xe0;
fk0> if (b&(1<<6)) crc^=0xc7;
fk0> if (b&(1<<7)) crc^=0x89;
fk0> return crc;
fk0>}

Не знаю, что ты здесь хотел нарисовать, но это никак не CRC в обычном понимании.

В обычном было бы примерно так:

uint_fast8_t crc_byte(uint_fast8_t byte, uint_fast8_t crc)
{
  uint_fast8_t old = crc;
  crc = byte;
  if (old & (1<<0)) crc ^= 0x07;
  ... аналогичные варианты для остальных битов ...
  return crc;
}


Может, твой код преобразуется в то, что делается по классике, но тут получается как минимум смещение на байт, и я с ходу не берусь предсказать результаты этого смещения и степень устойчивости результата.

Откуда код? Ты это взял из спецификации SMBus? Кстати, там точно передача начинается со старшего бита?

fk0> Вообще-то CRC считается и бестабличными методами достаточно быстро, если такая задача стоит. Опять же смотри пример. Все возражения "почему не 16-32 бита" -- потому что блоки не по 4 килобайта, а по десятку байт. А 16 бит принципиально ситуацию тут не изменит вообще.


Думаю, таки изменит. Не зря на Ethernet при типичном размере пакета в пару сотен байт уже применялся CRC-32.

Но твоя ситуация вообще-то показывает контекст не для CRC. CRC предназначен для случаев именно одиночных независимых искажений потока (изменения битов, выпадения/добавления целых байт). Причём на SMBus, аналогично RS-232, невозможно держать AFAIK линию данных всё время на одном уровне — потому что тогда не будут видны границы байтов. Ситуация, когда хвост пакета целиком становится битами одного значения, означает сбой уже в кодере или декодере протокола, а не помеху/сбой на линии. Такие вещи должны отлавливаться на другом уровне и обвинять CRC в их неотлове — нелепость.

Если ты хочешь проверить CRC на корректность детекта в условиях, в которых он предназначен работать — меняй произвольно 1 из ~100 байтов не обязательно в хвосте.
The God is real, unless declared integer.
Re[6]: Протокол на основе UDP
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 28.02.10 14:28
Оценка:
Здравствуйте, fk0, Вы писали:

Pzz>>IP'ная контрольная сумма не замечает вставления/удаления последовательности из четного количества нулей (насчет FF'ов не поручусь).


fk0> Вставка, удаление (кроме как с конца) и перестановка -- что-то по физическим причинам маловероятное в последовательном протоколе.


На RS-232 — сколько угодно. Прошёл левый импульс — приняли за стартовый бит.

fk0> А вот "обрывы" с замещением данных на 0 или 1,


Смотрю на типичную диаграмму I2C/SMBus, видим, что приёмник должен подтвердить приём — и что при этом линия SDA должна перейти в низкое состояние и обратно. То есть ситуация с тем, что кто-то замкнул линию, приведёт к стопу любых передач — они не смогут продолжиться. Максимум повреждения — один байт — лечится CRC.

Или у тебя суперклиенты на шине, которые в состоянии добавлять нули в чужую передачу именно в моменты передачи битов данных? Ну тогда это уже какая-то совершенно безумная ситуация.

fk0> или укорачивание пакета (удаление с конца), ну и просто искажение битов -- запросто.


Обычное искажение детектится CRC с хорошей надёжностью. Укорачивание должно опознаваться в рамках протокола.

В общем, не вижу, как реально можно получить такой кошмар, как ты рисовал.
The God is real, unless declared integer.
Re: Протокол на основе UDP
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 28.02.10 14:39
Оценка:
Здравствуйте, MikelSV, Вы писали:

MSV>Решил создать новый протокол на основе udp.

MSV>Преимущества:
MSV>* можно выкинуть select, и любые другие проверки. получение данных сразу по прибытию их.

Select тут ни при чём. Если это намёк на возможность посылать крупными порциями, то 1) за 64K вообще не вылезешь, 2) проблема с MTU.

MSV>* управление разрывами, UDP уже порван, и разрывы ему не страшны.


В случае NAT или stateful firewall — ещё как страшны.

MSV>* больший контроль соединения, управление разрывами, появляется возможность посылки разных данных, как потока, так и сообщений. так же есть идея приделать возможность посылки пакетов, не требующих подтверждения доставки.


На BEEP смотрели?

MSV>+ очень заманчивые перспективы, появляется много идей, которые просто невозможны на tcp, управляемом системой.


Например?

MSV>Возникающие вопросы:

MSV>* Все ли маршрутизаторы потянут такой неразрывный udp? то есть сколько времени они будут помнить об этом соединении?

Согласно настройкам.

MSV>Было бы неплохо обсудить саму техническую сторону. вопросов с организацией много, и мозги соображают достаточно медленно.

MSV>Так же уже видны проблемы в безопасности(в основном при подделке пакетов), что радости не добавляет.

Присоединяюсь к предложению брать готовое. SCTP, BEEP...
The God is real, unless declared integer.
Re[8]: Протокол на основе UDP
От: Pzz Россия https://github.com/alexpevzner
Дата: 28.02.10 17:55
Оценка:
Здравствуйте, netch80, Вы писали:

N>Кстати. Есть ли реализации NAT, которые пытаются проверять живость соединения? Для TCP это могла бы быть посылка пакета без данных, просто с ACK. Для UDP мне нравится метод имени Sipura — на пакет из четырёх нулевых байт отвечается пустым пакетом.


В смысле, бывает ли так, чтобы коробка с NAT'ом пыталась какими-то активными действиями проверить, живо ли еще соединение? Не знаю. А зачем это коробке?
Re[6]: Протокол на основе UDP
От: Pzz Россия https://github.com/alexpevzner
Дата: 28.02.10 17:57
Оценка:
Здравствуйте, netch80, Вы писали:

N>Стоп-стоп. Кирилл как раз говорит что CRC даёт слабую защиту (а контрольная сумма IP — достаточную). Ты приводишь пример на IP'шную сумму, хорошо. Но это как раз в противоречие его тезису. Я же хочу узнать, откуда такие странные выводы. То ли Кирилл оговорился и хотел сказать наоборот, то ли это противоречит тому, что я знал про эти средства.


По-моему, он хотел сказать наоборот. IP'ную сумму народ иногда тоже называет CRC'ом. Ума ни преложу, почему...
Re[6]: Протокол на основе UDP
От: fk0 Россия https://fk0.name
Дата: 28.02.10 19:10
Оценка:
Здравствуйте, netch80, Вы писали:

N>Здравствуйте, fk0, Вы писали:


fk0>> Пример ниже. Прекрасно видно, что на случайных данных, на совершенно разных последовательностях (случайных), даже на коротких (несколко байт) пакетах можно нарваться на ситуацию, когда CRC совпадает, а хвост пакета (а то и весь пакет!) испорчен нулём или FF. Позапускай программу несколько раз (./a.out | less). Что характерно -- CRC должен быть равен заполняющему (всё портящему) байту. Так вот в реальном приборе, где проблемы были, там, догадайся...


N>Во-первых, с самого начала: твой пример попросту с багом. Если его исправить как следует:

N>- ncrc=crc_byte(copy[n], crc);
N>+ ncrc=crc_byte(copy[n], ncrc);

N>то у меня получается в самом коротком случае 3 байта испорченных, иногда 4, обычно же оно не находит случаев короче чем 8 байт. Для CRC-8 это очень хороший результат. А твой пример умудряется находить даже последовательности с изменением одного последнего байта, что заведомо показывает на ошибочность твоего кода (собственно почему я и стал рыть).


Исправил. Так ведь получается. Вот пример для 1000 запусков:

$ (for x in `seq 1000`; do ./a.out | grep -m1 length; done) | sort -u
length=  4, tail=  2, fill=00, crc=88
length=  4, tail=  4, fill=FF, crc=DE
length=  5, tail=  2, fill=FF, crc=F0
length=  6, tail=  2, fill=FF, crc=82
length=  6, tail=  6, fill=00, crc=00
length=  7, tail=  3, fill=00, crc=52
length=  7, tail=  4, fill=00, crc=51
length=  7, tail=  5, fill=FF, crc=68
length=  7, tail=  6, fill=FF, crc=FA
length=  8, tail=  5, fill=FF, crc=61
length=  8, tail=  6, fill=FF, crc=4A
length=  8, tail=  7, fill=00, crc=5E
length=  9, tail=  7, fill=00, crc=5B
...


Как и ожидалось, ошибки не может быть только для однобайтовых пакетов. К слову, функция crc_byte здесь применена медленная (побитная) на всякий случай.


N>Далее по частям программы:


fk0>>/* compute CRC-8 for SMBUS (x^8 + x^2 + x + 1) */

fk0>>uint_fast8_t crc_byte(uint_fast8_t byte, uint_fast8_t crc)
fk0>>{
fk0>>uint_fast8_t b;
fk0>> b=byte^crc;
fk0>> if (b&(1<<0)) crc^=0x7;
fk0>> if (b&(1<<1)) crc^=0xe;
fk0>> if (b&(1<<2)) crc^=0x1c;
fk0>> if (b&(1<<3)) crc^=0x38;
fk0>> if (b&(1<<4)) crc^=0x70;
fk0>> if (b&(1<<5)) crc^=0xe0;
fk0>> if (b&(1<<6)) crc^=0xc7;
fk0>> if (b&(1<<7)) crc^=0x89;
fk0>> return crc;
fk0>>}
N>Не знаю, что ты здесь хотел нарисовать, но это никак не CRC в обычном понимании.

Это CRC с указанным полиномом и его результат для любых входных значений полностью совпадает с побитным алгоритмом CRC. Указанный полином на сайте smbus.org... Указанные коэффициенты для ксорки берутся из результатов вычисления таблицы CRC побитным алгоритмом и взятия каждого 2^N-го члена для N=0..7. Это оптимизированный алгоритм просто. И, кстати, на мелких контроллерах он может работать быстрее табличного (на гарвардских архитектурах доступ к данным в программной памяти -- медленный).

Тут закралась действительно ошибка и CRC считается неправильно:

 uint_fast8_t crc_byte(uint_fast8_t byte, uint_fast8_t crc)
 {
 uint_fast8_t b;
         b=byte^crc;
+        crc=0;
         if (b&(1<<0)) crc^=0x7;


Это патч какбы.

N>В обычном было бы примерно так:


Вот он, гарантированно работающий, но медленный (к слову, в приборе был он, не оптимизированный):

uint_fast8_t smbus_crc_byte(uint_fast8_t byte, uint_fast8_t crc)
{
uint_fast8_t y=8;
        do {
                if ((byte^crc)&0x80) crc<<=1, crc^=0x7;
                        else crc<<=1;
                byte<<=1;
        } while (--y);
        return crc;
}


Результаты вычислений совпадают (после исправления crc=0).

N>Может, твой код преобразуется в то, что делается по классике, но тут получается как минимум смещение на байт, и я с ходу не берусь предсказать результаты этого смещения и степень устойчивости результата.


См. выше, моя ошибка. Алгоритм переделывался с другого, для Maxim (бывший Dallas) 1-Wire, там биты в другую сторону сдвигаются, оттого и...

N>Откуда код? Ты это взял из спецификации SMBus? Кстати, там точно передача начинается со старшего бита?


Там точно (в I2C вообще) передача 7-м битом вперёд. Вот в 1-Wire -- наоборот, начиная с младшего.
IMHO начиная со старшего правильнее. Их удобнее на осциллографе разглядывать -- сразу можно в голове байт сложить...

fk0>> Вообще-то CRC считается и бестабличными методами достаточно быстро, если такая задача стоит. Опять же смотри пример. Все возражения "почему не 16-32 бита" -- потому что блоки не по 4 килобайта, а по десятку байт. А 16 бит принципиально ситуацию тут не изменит вообще.

N>Думаю, таки изменит. Не зря на Ethernet при типичном размере пакета в пару сотен байт уже применялся CRC-32.

N>Но твоя ситуация вообще-то показывает контекст не для CRC. CRC предназначен для случаев именно одиночных независимых искажений потока (изменения битов, выпадения/добавления целых байт).


Увы и ах. Именно так, именно для того он и предназначен. И в RS-232 будет замечательно работать. А где пакетная передача с обрывами посереди пакета и заполнением конца пакета одинаковым битом -- не канает CRC.

N> Причём на SMBus, аналогично RS-232, невозможно держать AFAIK линию данных всё время на одном уровне — потому что тогда не будут видны границы байтов. Ситуация, когда хвост пакета целиком становится битами одного значения, означает сбой уже в кодере или декодере протокола, а не помеху/сбой на линии. Такие вещи должны отлавливаться на другом уровне и обвинять CRC в их неотлове — нелепость.


Ничего подобного. Ситуация там такая: приём данных мастером, слейв отвалился по электрическим причинам (стоп-сигнал увидел и т.п.) На шине соответственно единица (обеспечивается резистором подтяжки) всё время. А мастер так уверенно читает все биты до конца пакета и *никак* не может знать, что слейв уже обмен закончил. Между байтами разделения в I2C нет, как и границ байтов в данном случае. В случае когда мастер записывал бы -- да, разделение есть, слейв должен на каждый байт ACKnowledge нулевым битом давать. А тут мастер должен ACK давать -- ну вот он и даёт, и читает дальше... Это в значительной степени проблема шины и протокола SMBUS (обязательный нулевой бит в конце пакета кардинально решал бы проблему).

N>Если ты хочешь проверить CRC на корректность детекта в условиях, в которых он предназначен работать — меняй произвольно 1 из ~100 байтов не обязательно в хвосте.


Если я поменяю 1 байт -- CRC-8 это всегда обнаружит. Надо 2 менять.

Кстати ещё пример неправильного применения CRC -- контрольный код записи в FLASH-памяти. Догадываешься уже почему? Ровно та же проблема. Массовое FF-чивание отдельных блоков. Контрольная сумма подходящей разрядности (весьма небольшой) опять же справляется гарантировано и это очевидно математически. Хотя и не справляется так хорошо с единичными сбоями, как CRC.
Re[7]: Протокол на основе UDP
От: fk0 Россия https://fk0.name
Дата: 28.02.10 19:19
Оценка:
Здравствуйте, netch80, Вы писали:

N>Здравствуйте, fk0, Вы писали:


Pzz>>>IP'ная контрольная сумма не замечает вставления/удаления последовательности из четного количества нулей (насчет FF'ов не поручусь).


fk0>> Вставка, удаление (кроме как с конца) и перестановка -- что-то по физическим причинам маловероятное в последовательном протоколе.

N>На RS-232 — сколько угодно. Прошёл левый импульс — приняли за стартовый бит.

Если в этот момент не было уже передачи. И скорей не RS-232 в голом виде, а модем -- вот там да, запросто вставки бывают, да и замены, и удаления...

fk0>> А вот "обрывы" с замещением данных на 0 или 1,

N>Смотрю на типичную диаграмму I2C/SMBus, видим, что приёмник должен подтвердить приём — и что при этом линия SDA должна перейти в низкое состояние и обратно. То есть ситуация с тем, что кто-то замкнул линию, приведёт к стопу любых передач — они не смогут продолжиться. Максимум повреждения — один байт — лечится CRC.

Разрыв линии при приёме мастером из слейва. Клок всегда выдаёт мастер (а не тот кто передаёт, в данном случае это слейв). Можно слейв из разъёма вырвать физически, можно добиться чтоб он сам отвалился по своей инициативе в условиях сильного искажения данных на шине.

N>Или у тебя суперклиенты на шине, которые в состоянии добавлять нули в чужую передачу именно в моменты передачи битов данных? Ну тогда это уже какая-то совершенно безумная ситуация.


Это кстати запросто. В длинной шине и сигналы "звенят", и 100 вольт на несколько наносекунд появлялось при включении двигателей... биты изгибались. Но это всегда ловилось на CRC, а вот обрывы -- нет.

fk0>> или укорачивание пакета (удаление с конца), ну и просто искажение битов -- запросто.

N>Обычное искажение детектится CRC с хорошей надёжностью. Укорачивание должно опознаваться в рамках протокола.
N>В общем, не вижу, как реально можно получить такой кошмар, как ты рисовал.

Этот кошмар реально был получен, как говорится проверено электроникой, практически. И он присутствует везде, где I2C и его производные.
Re: Протокол на основе UDP
От: Pepel Беларусь  
Дата: 01.03.10 07:21
Оценка:
Здравствуйте, MikelSV, Вы писали:

MSV>Решил создать новый протокол на основе udp.


неудачный выбор, при высокой утилизации сетки udp шные пакеты отбрасываются тучами, никакой мало-мальськи устойчивый сервис вы на udp не предложите
Re[2]: Протокол на основе UDP
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 01.03.10 07:56
Оценка:
Здравствуйте, Pepel, Вы писали:

MSV>>Решил создать новый протокол на основе udp.


P>неудачный выбор, при высокой утилизации сетки udp шные пакеты отбрасываются тучами,


UDP или вообще IP? Что-то я не замечал в алгоритмах контроля трафика какого-то особого предпочтения UDP.

P> никакой мало-мальськи устойчивый сервис вы на udp не предложите


Ну так и на IP его не предложить. А вот так, как сейчас работает IP (включая TCP) — можно сделать и на UDP без проблем. Только процессорных затрат больше (и трафика процентов на 5).
The God is real, unless declared integer.
Re[6]: Протокол на основе UDP
От: ononim  
Дата: 01.03.10 11:17
Оценка:
fk0>>>> Жизненный опыт. CRC даёт хреновейшую защиту от "сбоев оборудования" при обрыве, когда с середины пакета и до конца все байты FFFF или 0000 не важно.
N>>>Прошу примера. Мне сложно себе представить, чтобы правильно вычисленная и уложенная CRC не замечатала такие ситуации.
Pzz>>IP'ная контрольная сумма не замечает вставления/удаления последовательности из четного количества нулей (насчет FF'ов не поручусь).
Открою секрет: CRC и IP суммы ваще не дают никаких защит. То есть в том плане что полагаться на них попросту нельзя. Единственное их назначение — уменьшить нагрузку на оборудование в том случае когда из-за перегрузки или других причин идет куча левых пакетов. И все. По сути это оптимизация траффика, а не какая-то "защита".
Сама реализация контроля целостности подразумевает что никаких гарантий здесь ждать не надо и спорить не о чем. И если они вам нужны — делайте контроль сами, причем на том уровне надежности, который лично вам и нужен. Если вам реально важно чтобы данные дошли неполоманными — то без MD5/SHA? вам по любому уже не обойтись. А если уж речь заходит о MiM атаках — то велкам to SSL. А реализацию таких алгоритмов _внутри_ для всех протоколов tcp/ip стек себе позволить не может, даже с современным железом. Да и не зачем это — всегда правильнее строить протоколы on top друг друга, а не городить все в одном месте. Особенно учитывая, что такой мегаконтроль далеко не всем прикладным протоколам требуется.
Как много веселых ребят, и все делают велосипед...
Re[7]: Протокол на основе UDP
От: Pzz Россия https://github.com/alexpevzner
Дата: 01.03.10 11:48
Оценка:
Здравствуйте, ononim, Вы писали:

Pzz>>>IP'ная контрольная сумма не замечает вставления/удаления последовательности из четного количества нулей (насчет FF'ов не поручусь).

O>Открою секрет: CRC и IP суммы ваще не дают никаких защит. То есть в том плане что полагаться на них попросту нельзя. Единственное их назначение — уменьшить нагрузку на оборудование в том случае когда из-за перегрузки или других причин идет куча левых пакетов. И все. По сути это оптимизация траффика, а не какая-то "защита".

Ерунда. 16-битная контрольная сумма дает защиту, уменьшая вероятность незамеченных ошибок до 2^-16. MD5 — до 2^-128 и т.п. Что из этого выбрать, зависит от того, какая степень защиты нужна для вашей задачи и сколько вы за это готовы заплатить — в т.ч. в терминах вычислительных ресурсов. Вообще, говорить о защите вне контекста того, от чего мы защищаемся и зачем, некорректно.

Кстати, винчестеры (те, которые жесткие диски) полагаются на CRC32, считая, что вероятность аппаратной ошибки чтения, умноженная на 2^-32 достаточно мала для практических целей.
Re[3]: Протокол на основе UDP
От: Pepel Беларусь  
Дата: 01.03.10 12:00
Оценка:
Здравствуйте, netch80, Вы писали:

N>Здравствуйте, Pepel, Вы писали:


MSV>>>Решил создать новый протокол на основе udp.


P>>неудачный выбор, при высокой утилизации сетки udp шные пакеты отбрасываются тучами,


N>UDP или вообще IP? Что-то я не замечал в алгоритмах контроля трафика какого-то особого предпочтения UDP.


значит плохо наблюдали, udp пакеты при загрузки сети прост херятся без зазрения совести
Re[8]: Протокол на основе UDP
От: ononim  
Дата: 01.03.10 12:01
Оценка:
Pzz>>>>IP'ная контрольная сумма не замечает вставления/удаления последовательности из четного количества нулей (насчет FF'ов не поручусь).
O>>Открою секрет: CRC и IP суммы ваще не дают никаких защит. То есть в том плане что полагаться на них попросту нельзя. Единственное их назначение — уменьшить нагрузку на оборудование в том случае когда из-за перегрузки или других причин идет куча левых пакетов. И все. По сути это оптимизация траффика, а не какая-то "защита".
Pzz>Ерунда. 16-битная контрольная сумма дает защиту, уменьшая вероятность незамеченных ошибок до 2^-16. MD5 — до 2^-128 и т.п. Что из этого выбрать, зависит от того, какая степень защиты нужна для вашей задачи и сколько вы за это готовы заплатить — в т.ч. в терминах вычислительных ресурсов. Вообще, говорить о защите вне контекста того, от чего мы защищаемся и зачем, некорректно.
2^16 это 65536. Умножаем на MTU (~1.5kb) — получаем 100мб данных до появления ошибки, что по сути фигня. Потому это не защита а лишь _оптимизация_ трафика.


Pzz>Кстати, винчестеры (те, которые жесткие диски) полагаются на CRC32, считая, что вероятность аппаратной ошибки чтения, умноженная на 2^-32 достаточно мала для практических целей.

Это они в протоколе передачи разве что на CRC32 полагаются. При хранении данных давно используются более навороченные методы контроля/восстановления типа кода Рида-Соломона.
Как много веселых ребят, и все делают велосипед...
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.