Files
dat-thang/extra/dat-dpi/inc/dat_session.h
T
divorce b735900f2e 0.0.002
ddat interop with dat js
cable interop with cabal js
ddat's frontend = dat-thang
cable fe = cable-thang
dillo support based on cel's dillo-dat
bootstrap node
xplatform support

Signed-off-by: divo <418@cryspace.space>
2026-10-19 00:17:02 -04:00

152 lines
5.3 KiB
C

#ifndef DAT_SESSION_H
#define DAT_SESSION_H
#include <stddef.h>
#include <stdint.h>
#include "cesspool.h"
#include "dat.h"
#include "dat_wire.h"
#include "sleep_feed.h"
#include "sleep_replication.h"
#define DAT_SESSION_MAX_PEERS 64u
#define DAT_SESSION_CAP_METADATA_ONLY (UINT64_C(1) << 63)
enum dat_session_state {
DAT_SESSION_CLOSED = 0,
DAT_SESSION_OPEN = 1,
DAT_SESSION_DISCOVERING = 2,
DAT_SESSION_ACTIVE = 3,
DAT_SESSION_CLOSING = 4,
DAT_SESSION_FAILED = 5
};
enum dat_session_peer_state {
DAT_SESSION_PEER_DISCOVERED = 1,
DAT_SESSION_PEER_SECURE = 2,
DAT_SESSION_PEER_READY = 3,
DAT_SESSION_PEER_CLOSED = 4
};
enum dat_session_feed {
DAT_SESSION_METADATA = 0,
DAT_SESSION_CONTENT = 1,
DAT_SESSION_FEED_COUNT = 2
};
typedef struct dat_session_peer {
uint8_t peer_id[DAT_PEER_ID_BYTES];
uint8_t tx_nonce[24];
uint8_t rx_nonce[24];
uint8_t *rx_buffer;
size_t rx_buffer_len;
size_t rx_buffer_capacity;
uint64_t tx_offset;
uint64_t rx_offset;
uint8_t remote_feed_mask;
uint8_t local_feed_mask;
uint8_t remote_content_discovery[32];
int remote_content_pending;
dat_peer_t address;
uint64_t capabilities;
uint64_t payload_bytes_sent;
uint64_t payload_bytes_received;
int state;
int transport_authenticated;
int paused;
int tx_stream_encrypted;
int rx_stream_encrypted;
sleep_replication_t replication[DAT_SESSION_FEED_COUNT];
} dat_session_peer_t;
struct dat_session;
typedef int (*dat_session_send_fn)(void *context,
const uint8_t peer_id[DAT_PEER_ID_BYTES],
const uint8_t *frame, size_t frame_len);
typedef int (*dat_session_request_fn)(void *context,
const uint8_t peer_id[DAT_PEER_ID_BYTES],
enum dat_session_feed feed,
const dat_request_t *request);
/* Called when discovery yields a peer; establish an authenticated transport,
* then report success with dat_session_peer_secure(). */
typedef void (*dat_session_peer_fn)(void *context,
const dat_session_peer_t *peer);
typedef int (*dat_session_poll_fn)(void *context, int timeout_ms);
/*
* Session protocol state is separate from connection establishment. In the
* Cesspool path, call peer_secure only after the authenticated transport has
* bound this peer ID to the topic. In legacy Hypercore V6 mode, call it once
* the discovered TCP/uTP stream is connected; V6 performs its feed-key stream
* encryption inside the protocol itself.
*/
typedef struct dat_session {
int state;
int announcing;
int looking_up;
uint16_t port;
uint8_t archive_key[DAT_KEY_BYTES];
uint8_t discovery_topic[CESSPOOL_TOPIC_BYTES];
uint8_t peer_id[DAT_PEER_ID_BYTES];
uint8_t feed_keys[DAT_SESSION_FEED_COUNT][DAT_KEY_BYTES];
int content_key_known;
cesspool_t *cesspool;
sleep_feed_t *feeds[DAT_SESSION_FEED_COUNT];
dat_session_peer_t peers[DAT_SESSION_MAX_PEERS];
size_t peer_count;
dat_session_send_fn send;
dat_session_request_fn on_request;
dat_session_peer_fn on_peer;
void *peer_context;
dat_session_poll_fn poll_transport;
void *poll_context;
void *context;
} dat_session_t;
int dat_session_init(dat_session_t *session, cesspool_t *cesspool,
const uint8_t archive_key[DAT_KEY_BYTES],
const uint8_t peer_id[DAT_PEER_ID_BYTES], uint16_t port,
sleep_feed_t *metadata_feed,
const uint8_t metadata_key[DAT_KEY_BYTES],
sleep_feed_t *content_feed,
const uint8_t content_key[DAT_KEY_BYTES],
dat_session_send_fn send, void *context);
int dat_session_start(dat_session_t *session, int announce, int lookup);
int dat_session_set_peer_callback(dat_session_t *session,
dat_session_peer_fn callback, void *context);
int dat_session_set_transport_poll(dat_session_t *session,
dat_session_poll_fn poll, void *context);
int dat_session_peer_discovered(dat_session_t *session,
const cesspool_peer_t *discovered_peer);
int dat_session_peer_secure(dat_session_t *session,
const uint8_t peer_id[DAT_PEER_ID_BYTES],
int transport_authenticated);
/* For a metadata-only archive import, install the content key learned from
* the verified metadata header and announce that feed to connected peers. */
int dat_session_set_content_key(dat_session_t *session,
const uint8_t content_key[DAT_KEY_BYTES]);
int dat_session_expect_content_key(dat_session_t *session);
int dat_session_peer_down(dat_session_t *session,
const uint8_t peer_id[DAT_PEER_ID_BYTES]);
/* Pause this client's incoming block requests without dropping the peer. */
int dat_session_peer_pause(dat_session_t *session,
const uint8_t peer_id[DAT_PEER_ID_BYTES], int paused);
/* Accept arbitrary transport chunks. Partial and coalesced wire frames are buffered. */
int dat_session_receive(dat_session_t *session,
const uint8_t peer_id[DAT_PEER_ID_BYTES],
const uint8_t *frame, size_t frame_len);
int dat_session_request_block(dat_session_t *session,
const uint8_t peer_id[DAT_PEER_ID_BYTES],
enum dat_session_feed feed, uint64_t index,
uint64_t bytes);
int dat_session_send_block(dat_session_t *session,
const uint8_t peer_id[DAT_PEER_ID_BYTES],
enum dat_session_feed feed, uint64_t index);
int dat_session_tick(dat_session_t *session, uint64_t now_ms);
int dat_session_poll(dat_session_t *session, int timeout_ms, uint64_t now_ms);
int dat_session_close(dat_session_t *session);
dat_session_peer_t *dat_session_find_peer(dat_session_t *session,
const uint8_t peer_id[DAT_PEER_ID_BYTES]);
#endif /* DAT_SESSION_H */