summaryrefslogtreecommitdiff
path: root/client/client.h
diff options
context:
space:
mode:
Diffstat (limited to 'client/client.h')
-rw-r--r--client/client.h200
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