Files
utun2/tools/chatgui-android/libutun_lite/invite_link_c.h
T

75 lines
4.7 KiB
C

/* Старая отдельная копия C-кодека utun://; invite_link_c.c исключён из текущего UTUN_SOURCES.
* Рабочее общее API — src/chat/invite_link.h, Qt/Kotlin используют тот же формат версии 0x03.
* Эти структуры не следует смешивать с InviteData общего API; символы функций совпадают, вместе линковать нельзя.
* Копия декодирует версии 1/2/3, кодирует только 3; это описание оставшейся реализации, не API приложения. */
#ifndef INVITE_LINK_C_H
#define INVITE_LINK_C_H
#include <stdint.h>
#include <stddef.h>
#define INVITE_LINK_VERSION 0x03
#define INVITE_PUBKEY_SIZE 32
#define INVITE_ADDR_MAX 32
#define INVITE_PASS_MAX 128
#define INVITE_SNAME_MAX 64
#define INVITE_PROTO_UDP 0x01
#define INVITE_PROTO_TCP 0x02
#define INVITE_PROTO_REALITY 0x04 /* флаг reality-камуфляжа поверх TCP (reality-TCP = 0x06) */
#ifdef __cplusplus
extern "C" {
#endif
struct InviteAddrC {
int family; /* 4 — IPv4, 6 — IPv6; не AF_INET/AF_INET6. */
uint8_t address[16]; /* Сетевые байты; для IPv4 используются первые 4. */
uint8_t socketId; /* ID сокета в записи узла. */
uint8_t proto; /* Биты INVITE_PROTO_*; REALITY поверх TCP. */
uint16_t port; /* Host byte order; wire использует BE. */
};
/* Reality-параметры узла (node-global: одинаковы для всех reality-сокетов). */
struct InviteRealityC {
uint8_t has; /* 0 — блок отсутствует, иначе поля ниже заполнены. */
uint8_t short_id[8]; /* REALITY short ID. */
uint8_t server_pubkey[32]; /* X25519 ключ REALITY-сервера. */
uint8_t version[3]; /* Тройка байтов версии. */
char server_name[INVITE_SNAME_MAX]; /* NUL-строка SNI. */
};
struct InviteDataC {
uint64_t channelId; /* ID канала в host byte order. */
uint64_t join_key; /* 64-битный ключ входа (генерируется инвайтером) */
uint8_t pubkey[INVITE_PUBKEY_SIZE]; /* Ключ первого блока при decode, всех блоков при encode. */
uint64_t nodeId; /* Вычисляется из первого pubkey; encode не использует. */
uint8_t addrCount; /* Число элементов addrs, максимум INVITE_ADDR_MAX. */
struct InviteAddrC addrs[INVITE_ADDR_MAX]; /* Адреса всех прочитанных блоков без разделения по ключу. */
char password[INVITE_PASS_MAX]; /* Декодированный пароль, NUL; пусто = без пароля. */
uint8_t password_len; /* Длина декодированного пароля в байтах. */
struct InviteRealityC reality; /* Общие REALITY-параметры. */
};
/* link — len байтов с префиксом utun://; out предварительно обнулить. 0 — разобрано, -1 — ошибка.
* error_buf необязателен; частично изменённый out при ошибке не использовать. */
int invite_link_decode(const char* link, size_t link_len, struct InviteDataC* out,
char* error_buf, size_t error_buf_size);
/* encode invite data to utun://base64 string.
password=NULL означает пустой пароль в версии 0x03.
data.password/password_len/nodeId игнорируются; addrCount=1..32, строки должны быть NUL-терминированы.
Реализация также отвергает pubkey с первым нулевым байтом. Буфер брать с запасом: проверка ёмкости консервативна.
returns base64 length (excluding prefix and null), or -1 on error */
int invite_link_encode(const struct InviteDataC* data, const char* password, char* out, size_t out_size);
/* Сериализовать в caller-буфер Reality-префикс (has:1 + параметры при has) и адреса:
family(1) + socketId(1) + proto(1) + address(4|16) + port(2 BE)
returns total bytes written, or -1 if buf too small */
int invite_serialize_addrs(const struct InviteDataC* data, uint8_t* buf, size_t buf_size);
#ifdef __cplusplus
}
#endif
#endif /* INVITE_LINK_C_H */