You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
76 lines
4.1 KiB
76 lines
4.1 KiB
/* |
|
* dm_core.h — прямой p2p чат между двумя пользователями (DM) |
|
* |
|
* Отдельная подсистема (НЕ канал): без TOPO_GROUP/member_sync/merkle. |
|
* - conv_id и content_key детерминированно выводятся обеими сторонами |
|
* из своих ключей и pubkey пира (см. dm_crypto.h) — без переговоров. |
|
* - сообщения идут через etcp_router (прямое соединение или релей), |
|
* при недоступности пира — через dm_mailbox (storage-узлы). |
|
* - содержимое шифруется E2E (AES-256-CCM), запись подписывается Ed25519. |
|
* |
|
* Два независимых направленных потока (я→пир и пир→я) с монотонным seq. |
|
*/ |
|
|
|
#ifndef DM_CORE_H |
|
#define DM_CORE_H |
|
|
|
#include <stdint.h> |
|
#include <stddef.h> |
|
#include <string.h> |
|
|
|
struct UTUN_INSTANCE; |
|
|
|
#ifdef __cplusplus |
|
extern "C" { |
|
#endif |
|
|
|
/* ── Каноническое тело DM-сообщения (общий wire-формат dm_core и dm_mailbox) ── |
|
* [conv_id:8][seq:8][ts:8][author:8][ct_len:1][ct:ct_len][data_len:2][data_enc:data_len][sig:64] |
|
* data_enc — AES-256-CCM (шифротекст + tag), sig — Ed25519 автора по всем полям до sig. */ |
|
#define DM_MSG_FIXED_HDR 33 /* conv_id+seq+ts+author(32) + ct_len(1) — до ct */ |
|
#define DM_MSG_SIG_SIZE 64 |
|
|
|
/* Вычислить полную длину канонического тела из его заголовка. |
|
* Возвращает 1 и *out_len, либо 0 если буфер мал/повреждён. */ |
|
static inline int dm_msg_len(const uint8_t* msg, size_t avail, size_t* out_len) { |
|
if (!msg || avail < DM_MSG_FIXED_HDR) return 0; |
|
uint8_t ct_len = msg[32]; |
|
if (avail < (size_t)DM_MSG_FIXED_HDR + ct_len + 2) return 0; |
|
uint16_t data_len; |
|
memcpy(&data_len, msg + DM_MSG_FIXED_HDR + ct_len, 2); |
|
size_t total = (size_t)DM_MSG_FIXED_HDR + ct_len + 2 + data_len + DM_MSG_SIG_SIZE; |
|
if (avail < total) return 0; |
|
*out_len = total; |
|
return 1; |
|
} |
|
|
|
/* Жизненный цикл: инициализация после chat_core_init, destroy перед chat_core_destroy. */ |
|
int dm_core_init(struct UTUN_INSTANCE* inst); |
|
void dm_core_destroy(struct UTUN_INSTANCE* inst); |
|
|
|
/* Начать беседу с пользователем (peer). source_ch_id — канал, где нашли target |
|
* (общая группа; нужен для маршрутизации и подключения). Создаёт беседу если её |
|
* ещё нет, выводит conv_id/ключи, пытается установить прямое соединение. |
|
* Возвращает 0 при успехе, <0 при ошибке. */ |
|
int dm_start(struct UTUN_INSTANCE* inst, uint64_t peer_node_id, |
|
const uint8_t peer_x25519[32], const uint8_t peer_ed25519[32], |
|
const char* peer_name, const char* source_ch_id); |
|
|
|
/* Отправить сообщение в беседу. Шифрует, подписывает, сохраняет локально и |
|
* доставляет (прямое соединение при доступности пира, иначе mailbox). |
|
* conv_id — строковое представление (как в dm_conversations.conv_id). */ |
|
int dm_send(struct UTUN_INSTANCE* inst, const char* conv_id, const char* content_type, |
|
const uint8_t* data, uint32_t data_len); |
|
|
|
/* Список бесед в JSON: [{conv_id,peer_node_id,peer_name,last_ts,out_seq,in_seq}] */ |
|
int dm_list_conversations_json(struct UTUN_INSTANCE* inst, char* buf, size_t buf_size, size_t* out_len); |
|
|
|
/* Сообщения беседы в JSON (расшифрованные): [{dir,seq,ts,author,ct,data}] |
|
* count=0 → все, offset=0 → с начала. */ |
|
int dm_list_messages_json(struct UTUN_INSTANCE* inst, const char* conv_id, int count, int offset, |
|
char* buf, size_t buf_size, size_t* out_len); |
|
|
|
#ifdef __cplusplus |
|
} |
|
#endif |
|
#endif /* DM_CORE_H */
|
|
|