#ifndef DAT_WIRE_H #define DAT_WIRE_H #include #include enum dat_message_type { DAT_MSG_FEED = 0, DAT_MSG_HANDSHAKE = 1, DAT_MSG_INFO = 2, DAT_MSG_HAVE = 3, DAT_MSG_UNHAVE = 4, DAT_MSG_WANT = 5, DAT_MSG_UNWANT = 6, DAT_MSG_REQUEST = 7, DAT_MSG_CANCEL = 8, DAT_MSG_DATA = 9, DAT_MSG_EXTENSION = 15 }; typedef struct dat_feed_open { uint8_t discovery_key[32]; uint8_t nonce[24]; int has_nonce; } dat_feed_open_t; typedef struct dat_wire_message { uint64_t channel; uint64_t type; const uint8_t *payload; size_t payload_len; } dat_wire_message_t; #define DAT_PROTOCOL_BYTES 32u #define DAT_PEER_ID_BYTES 32u #ifndef DAT_NETWORK_PROTOCOL #define DAT_NETWORK_PROTOCOL "cesspool" #endif /* * The exact protocol token lives in the repository-root NETWORK_PROTOCOL * file. The Cesspool handshake carries it in `userData`; legacy Hypercore V6 * omits that application-owned field and uses the token to select its * discovery namespace and wire mode. This checkout defaults to `cesspool`. */ typedef struct dat_handshake { uint8_t protocol[DAT_PROTOCOL_BYTES]; uint8_t peer_id[DAT_PEER_ID_BYTES]; uint64_t capabilities; int has_peer_id; } dat_handshake_t; int dat_handshake_init(dat_handshake_t *handshake, const uint8_t peer_id[DAT_PEER_ID_BYTES], uint64_t capabilities); int dat_handshake_protocol_matches(const dat_handshake_t *handshake); typedef struct dat_range { uint64_t start; uint64_t length; } dat_range_t; typedef struct dat_info { uint8_t uploading; uint8_t downloading; } dat_info_t; typedef struct dat_request { uint64_t index; uint64_t bytes; uint8_t want_hash; uint8_t want_nodes; } dat_request_t; #define DAT_DATA_MAX_NODES 128u typedef struct dat_data_node { uint64_t index; uint64_t length; uint8_t hash[32]; } dat_data_node_t; typedef struct dat_data { uint64_t index; const uint8_t *value; size_t value_len; const uint8_t *proof; size_t proof_len; dat_data_node_t nodes[DAT_DATA_MAX_NODES]; size_t node_count; uint8_t signature[64]; int has_signature; } dat_data_t; typedef struct dat_cancel { uint64_t index; } dat_cancel_t; typedef struct dat_extension { uint64_t id; const uint8_t *message; size_t message_len; } dat_extension_t; /* Hypercore frames are length-prefixed; headers pack channel and type. */ int dat_wire_encode(const dat_wire_message_t *message, uint8_t *out, size_t capacity, size_t *written); int dat_wire_decode(dat_wire_message_t *message, const uint8_t *input, size_t input_len, size_t *consumed); int dat_handshake_encode(const dat_handshake_t *handshake, uint8_t *out, size_t capacity, size_t *written); int dat_handshake_decode(dat_handshake_t *handshake, const uint8_t *input, size_t input_len); int dat_feed_open_encode(const dat_feed_open_t *feed, uint8_t *out, size_t capacity, size_t *written); int dat_feed_open_decode(dat_feed_open_t *feed, const uint8_t *input, size_t input_len); int dat_range_encode(const dat_range_t *range, uint8_t *out, size_t capacity, size_t *written); int dat_range_decode(dat_range_t *range, const uint8_t *input, size_t input_len); /* WANT omits length to mean through the current end of a non-live feed. */ int dat_want_decode(dat_range_t *range, const uint8_t *input, size_t input_len, uint64_t feed_length); int dat_info_encode(const dat_info_t *info, uint8_t *out, size_t capacity, size_t *written); int dat_info_decode(dat_info_t *info, const uint8_t *input, size_t input_len); int dat_request_encode(const dat_request_t *request, uint8_t *out, size_t capacity, size_t *written); int dat_request_decode(dat_request_t *request, const uint8_t *input, size_t input_len); int dat_data_encode(const dat_data_t *data, uint8_t *out, size_t capacity, size_t *written); int dat_data_decode(dat_data_t *data, const uint8_t *input, size_t input_len); int dat_cancel_encode(const dat_cancel_t *cancel, uint8_t *out, size_t capacity, size_t *written); int dat_cancel_decode(dat_cancel_t *cancel, const uint8_t *input, size_t input_len); int dat_extension_encode(const dat_extension_t *extension, uint8_t *out, size_t capacity, size_t *written); int dat_extension_decode(dat_extension_t *extension, const uint8_t *input, size_t input_len); #endif