|
|
|
|
@ -604,8 +604,12 @@ int stream_ingest_path(struct UTUN_INSTANCE *inst, const uint8_t *wire, size_t l
|
|
|
|
|
int result = stream_buffer_put_path(s->buffer, wire, length, &retained); |
|
|
|
|
if (result == STREAM_OK || (result == STREAM_DUPLICATE && !s->anchored)) { |
|
|
|
|
if (!s->anchored) { |
|
|
|
|
s->anchored = 1; s->start_seq = s->next_seq = stream_read_be(wire + STREAM_BLOCK_SEQ_OFF, 8); |
|
|
|
|
uint64_t received = stream_read_be(wire + STREAM_BLOCK_SEQ_OFF, 8); |
|
|
|
|
uint64_t start = s->restarting && received < s->restart_from ? s->restart_from : received; |
|
|
|
|
s->anchored = 1; s->start_seq = s->next_seq = start; |
|
|
|
|
if (s->restarting && s->next_seq > s->restart_from) { s->restart_gap = 1; s->restart_last = s->next_seq - 1; } |
|
|
|
|
if (s->restarting) DEBUG_INFO(DEBUG_CATEGORY_STREAM, "stream restart anchored source=%llx received=%llu floor=%llu start=%llu", |
|
|
|
|
(unsigned long long)source, (unsigned long long)received, (unsigned long long)s->restart_from, (unsigned long long)start); |
|
|
|
|
s->restarting = 0; |
|
|
|
|
} |
|
|
|
|
session_schedule(s); |
|
|
|
|
@ -684,11 +688,15 @@ int stream_local_restart(struct UTUN_INSTANCE *inst, const struct stream_descrip
|
|
|
|
|
} |
|
|
|
|
struct stream_session *s = session_find(inst->stream, key->group_id, key->source_node_id); |
|
|
|
|
if (s->delivery) { uasync_call_soon_cancel(inst->ua, s->delivery); s->delivery = NULL; } |
|
|
|
|
if (s->anchored) { s->restarting = 1; s->restart_from = s->next_seq; } |
|
|
|
|
if (s->anchored) { |
|
|
|
|
if (!s->restart_gap) s->restart_from = s->next_seq; |
|
|
|
|
s->restarting = 1; |
|
|
|
|
} |
|
|
|
|
s->restart_gap = 0; |
|
|
|
|
s->anchored = s->end_delivered = 0; s->passed_before = s->next_seq = s->start_seq = 0; |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "stream receiver restart from end group=%llx source=%llx epoch=%llx retained=%u", |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "stream receiver restart from end group=%llx source=%llx epoch=%llx retained=%u floor=%llu known=%d", |
|
|
|
|
(unsigned long long)key->group_id, (unsigned long long)key->source_node_id, |
|
|
|
|
(unsigned long long)key->source_epoch, local.buffer != NULL); return STREAM_OK; |
|
|
|
|
(unsigned long long)key->source_epoch, local.buffer != NULL, (unsigned long long)s->restart_from, s->restarting); return STREAM_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Заимствованный локальный handle нужен только на время tick; владельцем остаётся сама подписка. */ |
|
|
|
|
|