#pragma once // #include #include #include // typedef uint8_t byte; typedef byte ipv4[ 4 ]; typedef byte ipv6[ 16 ]; typedef byte hash[ 32 ]; typedef byte public_key[ 32 ]; typedef byte private_key[ 32 ]; typedef byte signature[ 64 ]; const uint16_t default_port = 8040; enum client_input { // ask server for its information (responds with audit_response) audit_server = 0x9a, // ask server for a random set of neighbors // (input uint8_t neighbor_count, responds with neighbors_info) get_neighbors = 0x20, // monitor incoming packets // (input struct firehose_request, responds with firehose_reply) firehose = 0xf1, // give a packet to the relay // (input struct data_packet, responds with push_packet_result) push_packet = 0x88, // get a packet from the server // (input hash, responds with get_packet_result) get_packet = 0x87, // register a new neighbor relay to this server // (input struct relay_neighbor, responds with register_neighbor_result) register_neighbor = 0x73, }; enum server_reply { // pretty self-explanatory. error = 0x1, // type `struct relay_info` audit_response = 0xaf, // type `struct relay_neighbor[ neighbor_count ]` neighbors_info = 0x43, // type `uint64_t new_offset, struct data_packet[ count ]` firehose_reply = 0x6c, // type `bool result_code` push_packet_result = 0x4a, // type `struct data_packet` get_packet_result = 0x42, // type `bool result_code` register_neighbor_result = 0x6e, }; typedef uint8_t get_neighbors_request; struct firehose_request { uint8_t count; uint64_t offset; }; typedef uint64_t firehose_reply_new_offset; struct relay_neighbor { bool active; // set to 0 to indicate empty quick connect slot bool has_ipv4; // whether the neighbor supports ipv4 connection bool has_ipv6; // whether the neighbor supports ipv6 connection ipv4 v4_addr; // ipv4 address of the neighbor (if supported) ipv6 v6_addr; // ipv6 address of the neighbor (if supported) }; struct relay_info { // -- version info -- byte major_version; byte minor_version; // -- motd -- byte motd[ 128 ]; // -- capabilities -- struct { uint16_t retention_hours; // how many hours packets will be retained for bool can_store; // whether or not the relay is accepting new packets byte leading_zeros; // relay challenge level bool accepts_plain; // whether or not the relay accepts unencrypted packets } capabilities; // -- statistics -- struct { uint16_t neighbors; // current neighboring relay count for this relay uint64_t held_packets; // how many packets the relay is holding struct relay_neighbor quick_connect[ 4 ]; // four best neighbors for quick connection } statistics; }; // do not change #define MAX_RECIPIENTS 32 struct data_packet { // nonce + hash for PoW uint32_t nonce; hash hash; // content inside to be nonce + hashed struct { bool encrypted; // whether the contents is encrypted or plaintext uint64_t created_time_ms; // unix timestamp for creation time in milliseconds public_key author; // message author public_key author_signing_pub; // message signing pubkey uint8_t recipient_count; // number of recipients. leave as 0 for public. public_key recipients[ 32 ]; // up to 32 recipients for packet byte data[ 65536 ]; // packet data signature signature; // data signature } contents; }; const size_t CONTENTS_SIZE = 1 + 8 + 32 + 32 + 1 + (32 * MAX_RECIPIENTS) + 65536 + 64; const size_t PACKET_SIZE = 4 + 32 + (CONTENTS_SIZE);