diff --git a/doc/pm_invites.md b/doc/pm_invites.md index 67f55405..4291a7ac 100644 --- a/doc/pm_invites.md +++ b/doc/pm_invites.md @@ -14,8 +14,11 @@ GUI добавляет заголовок «Приглашение в групп Доставку, повтор и шифрование обеспечивает существующий механизм DM. После успешной отправки открывается личная беседа с получателем. -Срок действия ключа — **10 минут с момента создания**, а не получения PM. -Он указан в диалогах отправки и подключения. Поздняя offline-доставка +Срок действия ключа — **10 минут с момента последней успешной регистрации на каждом узле**. +Повторная регистрация того же ключа для того же канала тем же инвайтером продлевает срок. +Connection-узел сохраняет ключ при обработке регистрации, инвайтер — после её подтверждения; +при совпадении этих ролей запись одна. Для JOIN ключ должен действовать у обоих. +Получение PM срок не продлевает. Длительность указана в диалогах отправки и подключения. Поздняя offline-доставка может принести уже просроченную ссылку; в этом случае нужно новое приглашение. Ссылка не содержит время истечения, поэтому клиент показывает длительность, без обратного отсчёта и вычисления оставшегося времени. diff --git a/src/chat/chat_sync.h b/src/chat/chat_sync.h index 14f51db5..fe7f88ad 100644 --- a/src/chat/chat_sync.h +++ b/src/chat/chat_sync.h @@ -32,7 +32,8 @@ struct UASYNC; #define CS_MSG_SYNC_DONE 0x06 #define CS_MSG_ERROR 0x07 #define CS_MSG_CHANNEL_INVITE 0x0F /* push-invite: inviter → joiner */ -#define CS_MSG_JOIN_INFO_REQ 0x10 /* joiner → connection: {join_key:8} */ +/* В JOIN_INFO_REQ pass_len обязателен даже при пустом пароле (0); password передаётся без NUL. */ +#define CS_MSG_JOIN_INFO_REQ 0x10 /* joiner → connection: {join_key:8, pass_len:1, password:pass_len} */ #define CS_MSG_JOIN_INFO_RESP 0x11 /* connection → joiner: channel info + connection's member record */ #define CS_MSG_JOIN_REQUEST 0x12 /* joiner → connection: {join_key:8, member...} */ #define CS_MSG_JOIN_READY 0x13 /* connection → joiner: {group_id:8} */ @@ -79,7 +80,7 @@ void chat_sync_invite_to_channel_with_addrs( int addrs_data_len); /* Пригласить target_node_id в канал ch_id (inviter → joiner). - Отправляет CS_MSG_CHANNEL_INVITE с полной информацией о канале и своих адресах */ + Отправляет CS_MSG_CHANNEL_INVITE с описанием канала, подписями/профилем инвайтера и join_key. */ void chat_sync_invite_to_channel(struct UTUN_INSTANCE* inst, const char* ch_id, uint64_t target_node_id); /* Принять входящее приглашение — продолжить протокол из chat_join.h. */ @@ -95,7 +96,8 @@ void chat_sync_deny_invite(struct UTUN_INSTANCE* inst, uint64_t channel_id, uint это само по себе не даёт членства на других узлах. */ void chat_sync_join_channel(struct UTUN_INSTANCE* inst, const char* ch_id, uint64_t target_node_id); -/* Перезапустить групповые подключения для каналов без активных соединений. +/* Снять паузу и сбросить задержки повторных попыток во всех кешированных каналах с автоматическим планировщиком. + Планировщик пересматривает подключения; работающие соединения сохраняются. Вызывается из auto_socket при появлении/изменении сетевой связности. */ void chat_sync_retry_channels_on_socket_change(struct UTUN_INSTANCE* inst); diff --git a/src/chat/member_sync.h b/src/chat/member_sync.h index f7588259..63384a4d 100644 --- a/src/chat/member_sync.h +++ b/src/chat/member_sync.h @@ -127,7 +127,8 @@ void member_sync_cancel_channel(struct UTUN_INSTANCE* inst, const char* ch_id); * x25519 — X25519 публичный ключ (32 байта) * ed25519 — Ed25519 публичный ключ (32 байта) * join_sig — Ed25519 подпись join-сообщения (64 байта) - * сообщение: ch_x25519(32) || ch_ed25519(32) || node_id(8LE) || x25519(32) || join_ts(8LE) + * сообщение: ch_x25519(32) || ch_ed25519(32) || node_id(8) || x25519(32) || join_ts(8) + * node_id и join_ts копируются в порядке байтов хоста (см. member_sync_build_join_msg). * join_ts — NTP-синхронизированное время подписи (unix epoch seconds) * update_sig — подпись блока A (64 байта), update_ts — версия блока A * userinfo — метаданные узла (имя) в канале @@ -151,6 +152,7 @@ int member_sync_put(struct UTUN_INSTANCE* inst, const char* ch_id, /* * Строит сообщение для update_sig блока A (мембер): * join_sig(64) || update_ts(8) || userinfo(с NUL) + * update_ts копируется в порядке байтов хоста. * Используется и для подписи, и для верификации — байты обязаны совпадать. * Возвращает длину сообщения или -1. */ @@ -161,6 +163,7 @@ int member_sync_build_update_msg(const uint8_t* join_sig, uint64_t update_ts, /* * Строит сообщение для join_sig (каноническая раскладка 112 байт): * ch_x25519(32) || ch_ed25519(32) || node_id(8) || node_x25519(32) || join_ts(8) + * node_id и join_ts копируются в порядке байтов хоста, без преобразования endian. * Единственный источник истины для подписи и верификации join_sig во всех модулях. * Возвращает длину сообщения (112) или -1. */