diff options
Diffstat (limited to 'client/client.h')
| -rw-r--r-- | client/client.h | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/client/client.h b/client/client.h new file mode 100644 index 0000000..ee94d21 --- /dev/null +++ b/client/client.h @@ -0,0 +1,200 @@ +#pragma once + +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> + +typedef uint8_t byte; +typedef byte hash[ 32 ]; +typedef byte public_key[ 32 ]; +typedef byte private_key[ 32 ]; +typedef byte signature[ 64 ]; +typedef byte ipv4[ 4 ]; +typedef byte ipv6[ 16 ]; + +#define MAX_RECIPIENTS 32 + +struct relay_neighbor { + bool active; + bool has_ipv4; + bool has_ipv6; + ipv4 v4_addr; + ipv6 v6_addr; +}; + +struct relay_info { + byte major_version; + byte minor_version; + byte motd[ 128 ]; + struct { + uint16_t retention_hours; + bool can_store; + byte leading_zeros; + bool accepts_plain; + } capabilities; + struct { + uint16_t neighbors; + uint64_t held_packets; + struct relay_neighbor quick_connect[ 4 ]; + } statistics; +}; + +struct data_packet { + uint32_t nonce; + hash hash; + struct { + bool encrypted; + uint64_t created_time_ms; + public_key author; + public_key author_signing_pub; + uint8_t recipient_count; + public_key recipients[ 32 ]; + byte data[ 65536 ]; + signature signature; + } contents; +}; + +// from libsodium +#ifndef SIGN_PUBLICKEYBYTES + #define SIGN_PUBLICKEYBYTES 32 +#endif +#ifndef SIGN_SECRETKEYBYTES + #define SIGN_SECRETKEYBYTES 64 +#endif + +typedef unsigned char sign_public_key[ SIGN_PUBLICKEYBYTES ]; +typedef unsigned char sign_secret_key[ SIGN_SECRETKEYBYTES ]; + +typedef struct { + public_key encryption_pub; + private_key encryption_priv; + sign_public_key signing_pub; + sign_secret_key signing_priv; +} keypair; + +struct data_packet_list { + struct data_packet* packets; // caller must free this + uint16_t count; + uint64_t new_offset; +}; + +typedef enum { + MP_CLIENT_SUCCESS = 0, + MP_CLIENT_ERROR_NETWORK_FAIL, + MP_CLIENT_ERROR_INVALID_ADDRESS, + MP_CLIENT_ERROR_CONNECTION_FAILED, + MP_CLIENT_ERROR_SEND_FAILED, + MP_CLIENT_ERROR_RECV_FAILED, + MP_CLIENT_ERROR_SERVER_BUSY, // 418 teapot + MP_CLIENT_ERROR_INVALID_RESPONSE, + MP_CLIENT_ERROR_DESERIALIZE_FAILED, + MP_CLIENT_ERROR_ALLOC_FAILED, + MP_CLIENT_ERROR_FILE_NOT_FOUND, + MP_CLIENT_ERROR_FILE_READ_FAILED, + MP_CLIENT_ERROR_BAD_ARGUMENT, +} mp_client_error_t; + +/** + * @brief Get server information and capabilities. + * @param ip Server IP address (IPv4 or IPv6). + * @param port Server port. + * @param out_info Pointer to a struct where the server info will be stored. + * @return MP_CLIENT_SUCCESS on success, or an error code on failure. + */ +mp_client_error_t mp_get_server_info(const char* ip, int port, struct relay_info* out_info); + +/** + * @brief Get a list of neighbors from the server. + * @param ip Server IP address. + * @param port Server port. + * @param count Number of neighbors to request. + * @param out_neighbors Pointer to a pointer that will be updated to point to a newly allocated + * array of neighbors. The caller is responsible for freeing this memory. + * @param out_count Pointer to a byte where the actual number of received neighbors will be stored. + * @return MP_CLIENT_SUCCESS on success, or an error code on failure. + */ +mp_client_error_t mp_get_server_neighbors( + const char* ip, int port, byte count, struct relay_neighbor** out_neighbors, byte* out_count); + +/** + * @brief Push a packet to the server. + * @param ip Server IP address. + * @param port Server port. + * @param packet The data packet to push. + * @param out_success Pointer to a boolean that will be true if the server accepted the packet, + * false otherwise. + * @return MP_CLIENT_SUCCESS on success, or an error code on failure. + */ +mp_client_error_t +mp_push_packet(const char* ip, int port, struct data_packet packet, bool* out_success); + +/** + * @brief Get a specific packet from the server by its hash. + * @param ip Server IP address. + * @param port Server port. + * @param packet_hash The hash of the packet to retrieve. + * @param out_packet Pointer to a struct where the retrieved packet will be stored. + * @return MP_CLIENT_SUCCESS on success, or an error code on failure. + */ +mp_client_error_t +mp_get_packet(const char* ip, int port, const hash packet_hash, struct data_packet* out_packet); + +/** + * @brief Get a batch of packets from the server's firehose stream. + * @param ip Server IP address. + * @param port Server port. + * @param offset The starting offset in the firehose stream. + * @param count The maximum number of packets to retrieve. + * @param out_list Pointer to a data_packet_list struct. The 'packets' member will be allocated by + * the function and must be freed by the caller. + * @return MP_CLIENT_SUCCESS on success, or an error code on failure. + */ +mp_client_error_t mp_get_firehose_packets( + const char* ip, int port, uint64_t offset, uint16_t count, struct data_packet_list* out_list); + +/** + * @brief Create a data packet from a raw byte buffer. + * @param input The raw data buffer. + * @param input_len The length of the data buffer. + * @param recipient_count The number of recipients. + * @param recipients An array of recipient public keys. + * @param author_keys The keypair of the packet author. + * @return A new data_packet struct. + */ +struct data_packet mp_create_packet_from_bytes( + const byte* input, + size_t input_len, + byte recipient_count, + hash* recipients, + keypair author_keys); + +/** + * @brief Create a data packet by reading the contents from a file. + * @param filename The path to the file. + * @param recipient_count The number of recipients. + * @param recipients An array of recipient public keys. + * @param author_keys The keypair of the packet author. + * @param out_packet Pointer to a struct where the created packet will be stored. + * @return MP_CLIENT_SUCCESS on success, or an error code on failure. + */ +mp_client_error_t mp_create_packet_from_file( + const char* filename, + byte recipient_count, + hash* recipients, + keypair author_keys, + struct data_packet* out_packet); + +/** + * @brief Run Proof-of-Work on a packet to find a nonce that satisfies the leading zeros + * requirement. + * @param packet The input packet. The 'nonce' and 'hash' fields will be modified. + * @param leading_zeros The number of leading zero bits required for the hash. + * @return The modified packet with a valid nonce and hash. + */ +struct data_packet mp_run_pow(struct data_packet packet, byte leading_zeros); + +/** + * @brief Generates a new encryption and signing keypair. + * @return A new keypair struct. + */ +keypair mp_generate_keypair(void);
\ No newline at end of file |
