Browse Source

Validate short media batches with an embedded source signature

master
evgeny 7 days ago
parent
commit
98d1e40bf3
  1. 2
      src/stream/stream_member.h
  2. 4
      src/stream/stream_source.h
  3. 5
      tests/test_stream_media.c

2
src/stream/stream_member.h

@ -1,5 +1,5 @@
/* Строковые опции подписанного блока мембера, без отдельного протокола объявлений. /* Строковые опции подписанного блока мембера, без отдельного протокола объявлений.
* stream_source = epoch(16 hex):n:r:RS-size; отсутствие/пустое значение — не публикует. * stream_source = epoch(16 hex):n:r:max-RS-size; отсутствие/пустое значение — не публикует.
* stream_subscriptions = source(16 hex):epoch(16 hex)[:r],...; :r — только помощь, без локального зрителя. * stream_subscriptions = source(16 hex):epoch(16 hex)[:r],...; :r — только помощь, без локального зрителя.
* Указанная в stream_source собственная трансляция также должна быть в subscriptions. * Указанная в stream_source собственная трансляция также должна быть в subscriptions.
* load проверяет подпись профиля и принадлежность ключа источника, BGP-доступность — отдельно. * load проверяет подпись профиля и принадлежность ключа источника, BGP-доступность — отдельно.

4
src/stream/stream_source.h

@ -1,4 +1,4 @@
/* Источник непрозрачных байтов: одна подписанная FEC-пачка за ограниченный write, /* Источник непрозрачных байтов: одна подпись внутри FEC-пачки за ограниченный write,
* неполная пачка сбрасывается таймером 100 мс, все блоки сначала сохраняются в кольце. * неполная пачка сбрасывается таймером 100 мс, все блоки сначала сохраняются в кольце.
* Один uasync-поток; источник сам владеет encoder/кольцом/таймером. NCD здесь ещё нет. * Один uasync-поток; источник сам владеет encoder/кольцом/таймером. NCD здесь ещё нет.
* ready вызывается после помещения всей пачки и может читать кольцо; write/finish/destroy * ready вызывается после помещения всей пачки и может читать кольцо; write/finish/destroy
@ -27,7 +27,7 @@ struct stream_buffer *stream_source_buffer(struct stream_source *source);
* accepted получает принятую часть даже при ошибке; нулевой write допустим и не создаёт пустую пачку. * accepted получает принятую часть даже при ошибке; нулевой write допустим и не создаёт пустую пачку.
* Ошибка публикации/таймера делает источник failed; его уничтожают, не повторяют принятую часть как новую трансляцию. */ * Ошибка публикации/таймера делает источник failed; его уничтожают, не повторяют принятую часть как новую трансляцию. */
int stream_source_write(struct stream_source *source, const uint8_t *data, size_t length, size_t *accepted); int stream_source_write(struct stream_source *source, const uint8_t *data, size_t length, size_t *accepted);
/* Один непустой блок = одна немедленно опубликованная FEC-пачка, length <= input_capacity. /* Один непустой блок = одна немедленная FEC-пачка с минимальным размером частей, length <= input_capacity.
* Режим выбирается первой непустой записью; побайтовый и блочный режимы не смешиваются. */ * Режим выбирается первой непустой записью; побайтовый и блочный режимы не смешиваются. */
int stream_source_write_block(struct stream_source *source, const uint8_t *data, size_t length); int stream_source_write_block(struct stream_source *source, const uint8_t *data, size_t length);
/* Сбросить остаток и остановить приём; повторный finish допустим, кольцо доступно до destroy. */ /* Сбросить остаток и остановить приём; повторный finish допустим, кольцо доступно до destroy. */

5
tests/test_stream_media.c

@ -86,11 +86,12 @@ static void test_batches(void) {
uint8_t input[7080], output[7080]; size_t length = 0; uint8_t input[7080], output[7080]; size_t length = 0;
CHECK(stream_media_encode(&b, input, sizeof(input), &length) == STREAM_OK); CHECK(stream_media_encode(&b, input, sizeof(input), &length) == STREAM_OK);
const uint8_t *blocks[RS_MAX_BLOCKS]; const uint8_t *blocks[RS_MAX_BLOCKS];
CHECK(stream_encoder_encode(encoder, 0, 1, 0, input, length, blocks) == STREAM_OK); size_t part_size = 0;
CHECK(stream_encoder_encode(encoder, 0, 1, 0, input, length, blocks, &part_size) == STREAM_OK && part_size < 1300);
for (unsigned a = 0; a < 8; a++) for (unsigned c = a + 1; c < 8; c++) { for (unsigned a = 0; a < 8; a++) for (unsigned c = a + 1; c < 8; c++) {
struct stream_buffer *buffer = NULL; size_t decoded = 0; struct stream_buffer *buffer = NULL; size_t decoded = 0;
CHECK(stream_buffer_create(&buffer, &d, stream_encoder_public_key(encoder), 8 * 1300) == STREAM_OK); CHECK(stream_buffer_create(&buffer, &d, stream_encoder_public_key(encoder), 8 * 1300) == STREAM_OK);
for (unsigned i = 0; i < 8; i++) if (i != a && i != c) CHECK(stream_buffer_put(buffer, blocks[i], 1300) == STREAM_OK); for (unsigned i = 0; i < 8; i++) if (i != a && i != c) CHECK(stream_buffer_put(buffer, blocks[i], part_size) == STREAM_OK);
CHECK(stream_buffer_decode(buffer, 0, output, sizeof(output), &decoded) == STREAM_OK); CHECK(stream_buffer_decode(buffer, 0, output, sizeof(output), &decoded) == STREAM_OK);
CHECK(decoded == length && !memcmp(input, output, length)); CHECK(decoded == length && !memcmp(input, output, length));
struct stream_media_block parsed; CHECK(stream_media_parse(output, decoded, &parsed) == STREAM_OK); struct stream_media_block parsed; CHECK(stream_media_parse(output, decoded, &parsed) == STREAM_OK);

Loading…
Cancel
Save