|
|
|
|
@ -392,7 +392,7 @@ static void peer_pump(void *arg) {
|
|
|
|
|
struct stream_peer *p = arg; p->pump = NULL; |
|
|
|
|
if (!p->up || !p->own_epoch || p->network->stopping) return; |
|
|
|
|
struct ETCP_CONN *conn = node_conn_direct_get_conn(p->ncd); |
|
|
|
|
if (!conn || !conn->send_input_q || conn->state == 2 || conn->close_requested) return; |
|
|
|
|
if (!conn || !conn->send_input_q || conn->state == 2 || conn->close_requested || conn->reinit_pending || !conn->initialized) return; |
|
|
|
|
if (conn->send_input_q->count) { |
|
|
|
|
p->wait_q = conn->send_input_q; |
|
|
|
|
if (queue_waiter_wait(p->wait_q, &p->waiter, send_ready, p) < 0) |
|
|
|
|
@ -554,7 +554,11 @@ static void dispatch(struct stream_network *net, uint64_t sender, const uint8_t
|
|
|
|
|
} else if (m.command == STREAM_CMD_END && f && f->info.state == STREAM_RECEIVE_ACTIVE) { |
|
|
|
|
if (stream_ingest_end(net->inst, &f->descriptor, m.payload, m.length) == STREAM_OK) f->info.state = STREAM_RECEIVE_ENDED; |
|
|
|
|
else flow_close(f, STREAM_REASON_PROTOCOL, 1); |
|
|
|
|
} else if (m.command == STREAM_CMD_RENEW && f && !m.length) f->deadline = get_time_tb() + STREAM_LEASE_TB; |
|
|
|
|
} else if (m.command == STREAM_CMD_RENEW && f && !m.length) { |
|
|
|
|
f->deadline = get_time_tb() + STREAM_LEASE_TB; |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_STREAM, "stream lease renewed peer=%llx handle=%llu deadline=%llu", |
|
|
|
|
(unsigned long long)sender, (unsigned long long)m.handle, (unsigned long long)f->deadline); |
|
|
|
|
} |
|
|
|
|
else if (m.command == STREAM_CMD_UNSUBSCRIBE && f && m.length == 1) flow_close(f, m.payload[0], 1); |
|
|
|
|
else if ((m.command == STREAM_CMD_CLOSED || m.command == STREAM_CMD_REJECT) && f && (m.length == 1 || m.length == 17)) |
|
|
|
|
flow_close(f, m.payload[0], 0); |
|
|
|
|
@ -674,6 +678,25 @@ void stream_network_cancel(struct stream_network *net, const struct stream_descr
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Исключение поставщика/получателя или self закрывает выдачи, сохраняя локальное кольцо остальных трансляций. */ |
|
|
|
|
void stream_network_membership_changed(struct stream_network *net, uint64_t node, const char *channel) { |
|
|
|
|
if (!net || net->stopping || !channel) return; |
|
|
|
|
for (struct stream_peer *p = net->peers; p; p = p->next) { |
|
|
|
|
if (node != p->node_id && node != net->inst->node_id) continue; |
|
|
|
|
p->busy++; |
|
|
|
|
for (struct STREAM_RECEIVE *f = p->flows; f; f = f->next) { |
|
|
|
|
if (f->info.state == STREAM_RECEIVE_CLOSED) continue; |
|
|
|
|
struct TOPO_GROUP *group = topo_groups_find(net->inst->topo_groups, f->descriptor.group_id); |
|
|
|
|
if (!group || strcmp(group->channel_id, channel)) continue; |
|
|
|
|
struct stream_member_state state; |
|
|
|
|
int result = stream_member_load(net->inst, group->group_id, node, &state, NULL); |
|
|
|
|
if (result == STREAM_ERR_NOT_MEMBER || result == STREAM_ERR_SIGNATURE || result == STREAM_ERR_FORMAT) |
|
|
|
|
flow_close(f, STREAM_REASON_MEMBER, 1); |
|
|
|
|
} |
|
|
|
|
p->busy--; peer_sweep(p); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int stream_receive_open(struct STREAM_HANDLE *subscription, uint64_t node, uint8_t sub, uint64_t seq, struct STREAM_RECEIVE **out) { |
|
|
|
|
struct UTUN_INSTANCE *inst; struct stream_descriptor d; |
|
|
|
|
if (!out || *out || stream_handle_context(subscription, &inst, &d) != STREAM_OK || sub >= d.n || !node || node == inst->node_id) { |
|
|
|
|
|