From 5b93db7463e58d99bfaf58e12018731c925fca05 Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Sun, 3 Mar 2024 18:12:44 -0500 Subject: [PATCH] A buncha muncha cruncha .h docs. Also add vim temporary files to .gitignore. --- .gitignore | 8 +- src/ssb.h | 365 ++++++++++++++++++++++++++++++++++++++++++++++- src/ssb.import.h | 15 ++ src/ssb.js.h | 5 + src/ssb.rpc.h | 10 ++ src/ssb.tests.h | 32 +++++ 6 files changed, 428 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 55365e2e..4dd27d0b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,10 @@ -**/node_modules -.keys -.zsign_cache/ db.* deps/ios_toolchain/ deps/openssl/ dist/ +.keys +**/node_modules out +*.swo +*.swp +.zsign_cache/ diff --git a/src/ssb.h b/src/ssb.h index d37fe057..a319f67a 100644 --- a/src/ssb.h +++ b/src/ssb.h @@ -30,6 +30,9 @@ enum k_ssb_blob_bytes_max = 5 * 1024 * 1024, }; +/** +** The type of change to a set of connections. +*/ typedef enum _tf_ssb_change_t { k_tf_ssb_change_create, @@ -37,12 +40,17 @@ typedef enum _tf_ssb_change_t k_tf_ssb_change_remove, } tf_ssb_change_t; +/** An SSB instance. */ typedef struct _tf_ssb_t tf_ssb_t; -typedef struct _tf_ssb_rpc_t tf_ssb_rpc_t; +/** An SSB connection. */ typedef struct _tf_ssb_connection_t tf_ssb_connection_t; +/** A trace instance. */ typedef struct _tf_trace_t tf_trace_t; +/** An SQLite database handle. */ typedef struct sqlite3 sqlite3; +/** An event loop. */ typedef struct uv_loop_s uv_loop_t; +/** A socket address. */ struct sockaddr_in; enum @@ -52,15 +60,26 @@ enum k_blob_id_len = 53, }; +/** +** Statistics about an SSB instance. +*/ typedef struct _tf_ssb_stats_t { + /** Number of active connections. */ int connections; + /** Number of active hosts discovered by network broadcast. */ int broadcasts; + /** Number of messages stored. */ int messages_stored; + /** Number of blobs stored. */ int blobs_stored; + /** Number of RPC messages received. */ int rpc_in; + /** Number of RPC messages sent. */ int rpc_out; + /** Number of active RPC requests. */ int request_count; + /** Number of callbacks registered. */ struct { int rpc; @@ -71,90 +90,428 @@ typedef struct _tf_ssb_stats_t } callbacks; } tf_ssb_stats_t; +/** +** State about requesting blobs. +*/ typedef struct _tf_ssb_blob_wants_t { + /** The request number of the blob.wants RPC call. */ int32_t request_number; + /** The number of blob wants we are waiting for a response to. */ int wants_sent; + /** The last blob ID considered. */ char last_id[k_blob_id_len]; } tf_ssb_blob_wants_t; +/** +** A queue for storing messages. +*/ typedef struct _tf_ssb_store_queue_t { + /** The first node in the queue. */ void* head; + /** The last node in the queue. */ void* tail; + /** Whether the queue is currently running. */ bool running; } tf_ssb_store_queue_t; +/** +** Create an SSB instance. +** @param loop The event loop to use or NULL to create a new one. +** @param context The JS context to use or NULL to create a new one. +** @param db_path The path to the SQLite database to use. +** @param network_key The SSB network key to use or NULL to use the standard key. +*/ tf_ssb_t* tf_ssb_create(uv_loop_t* loop, JSContext* context, const char* db_path, const char* network_key); + +/** +** Destroy an SSB instance. +** @param ssb The SSB instance to destroy. +*/ void tf_ssb_destroy(tf_ssb_t* ssb); +/** +** Start optional periodic work. +** @param ssb The SSB instance. +*/ void tf_ssb_start_periodic(tf_ssb_t* ssb); + +/** +** Control logging verbosity. +** @param ssb The SSB instance. +** @param verbose True to log messages for every RPC message sent and received. +*/ void tf_ssb_set_verbose(tf_ssb_t* ssb, bool verbose); +/** +** Acquire an SQLite database for unrestricted reading. Release qith tf_ssb_release_db_reader(). +** @param ssb The SSB instance. +** @return A database with full read access to the database. +*/ sqlite3* tf_ssb_acquire_db_reader(tf_ssb_t* ssb); + +/** +** Acquire an SQLite database for restricted reading. Release qith +** tf_ssb_release_db_reader(). +** @param ssb The SSB instance. +** @return A database with read access to a safe subset of the database. +*/ sqlite3* tf_ssb_acquire_db_reader_restricted(tf_ssb_t* ssb); + +/** +** Release a database acquired with tf_ssb_acquire_db_reader() or +** tf_ssb_acquire_db_reader_restricted(). +** @param ssb The SSB instance. +** @param db The database. +*/ void tf_ssb_release_db_reader(tf_ssb_t* ssb, sqlite3* db); + +/** +** Acquire an SQLite database with full write access to the database. Release +** with tf_ssb_release_db_writer(). +** @param ssb The SSB instance. +** @return The writable database. +*/ sqlite3* tf_ssb_acquire_db_writer(tf_ssb_t* ssb); + +/** +** Release a database acquired with tf_ssb_acquire_db_writer(). +** @param ssb The SSB instance. +** @param db The database. +*/ void tf_ssb_release_db_writer(tf_ssb_t* ssb, sqlite3* db); + +/** +** Get the SSB instance's event loop. +** @param ssb The SSB instance. +** @return The loop. +*/ uv_loop_t* tf_ssb_get_loop(tf_ssb_t* ssb); +/** +** Generate a public/private key pair for the SSB instance. +** @param ssb The SSB instance. +*/ void tf_ssb_generate_keys(tf_ssb_t* ssb); + +/** +** Generate a public/private key pair and store in buffers. +** @param[out] out_public Buffer to receive the public key. +** @param public_size Size of the public key buffer. +** @param[out] out_private Buffer to receive the private key. +** @param private_size Size of the private key buffer. +*/ void tf_ssb_generate_keys_buffer(char* out_public, size_t public_size, char* out_private, size_t private_size); + +/** +** Get the private key of the SSB instance. +** @param ssb The SSB instance. +** @param[out] out_private Buffer to receive the private key. +** @param private_size The size of the private key buffer. +*/ void tf_ssb_get_private_key(tf_ssb_t* ssb, uint8_t* out_private, size_t private_size); +/** +** Set the trace instance to use for the SSB instance. +** @param ssb The SSB instance. +** @param trace The trace instance to use. +*/ void tf_ssb_set_trace(tf_ssb_t* ssb, tf_trace_t* trace); + +/** +** Get the SSB instance's trace instance. +** @param ssb The SSB instance. +** @return The trace instance. +*/ tf_trace_t* tf_ssb_get_trace(tf_ssb_t* ssb); +/** +** Get the SSB istance's JS context. +** @param ssb The SSB instance. +** @return The JS context. +*/ JSContext* tf_ssb_get_context(tf_ssb_t* ssb); +/** +** Begin listening for SSB discovery messages. +** @param ssb The SSB instance. +** @param linger True if listening for broadcasts should keep the event loop alive. +*/ void tf_ssb_broadcast_listener_start(tf_ssb_t* ssb, bool linger); + +/** +** Begin sending SSB discovevry messages. +** @param ssb The SSB instance. +*/ void tf_ssb_broadcast_sender_start(tf_ssb_t* ssb); + +/** +** Run the SSB instance until there is no work to do or stopped. +** @param ssb The SSB instance. +*/ void tf_ssb_run(tf_ssb_t* ssb); + +/** +** Sign an SSB message. +** @param ssb The SSB instance. +** @param author The author's public key. +** @param private_key The author's private key. +** @param message The message to sign. +** @return The signed message. +*/ JSValue tf_ssb_sign_message(tf_ssb_t* ssb, const char* author, const uint8_t* private_key, JSValue message); + +/** +** Get the server's identity. +** @param ssb The SSB instance. +** @param[out] out_id A buffer populated with the identity. +** @param out_id_size The size of the identity buffer. +** @return True if the identity was successfully retrieved. +*/ bool tf_ssb_whoami(tf_ssb_t* ssb, char* out_id, size_t out_id_size); +/** +** Call a callback for each active host discovered by network discovery broadcast. +** @param ssb The SSB instance. +** @param callback The callback. +** @param user_data User data for the callback. +*/ void tf_ssb_visit_broadcasts( tf_ssb_t* ssb, void (*callback)(const char* host, const struct sockaddr_in* addr, tf_ssb_connection_t* tunnel, const uint8_t* pub, void* user_data), void* user_data); +/** +** Get the identities of all active connections. +** @param ssb The SSB instance. +** @return A NULL-terminated array of SSB identities. Free with tf_free(). +*/ const char** tf_ssb_get_connection_ids(tf_ssb_t* ssb); + +/** +** Retrieve a list of active connections. +** @param ssb The SSB instance. +** @param[out] out_connections An array to be populated with the connections. +** @param out_connections_count The size of the connections array. +** @return The number of connections populated in out_connections. +*/ int tf_ssb_get_connections(tf_ssb_t* ssb, tf_ssb_connection_t** out_connections, int out_connections_count); + +/** +** Establish an SHS connection with a host. +** @param ssb The SSB instance. +** @param host The host name or address. +** @param port The host's SHS port. +** @param key The host's SSB identity. +*/ void tf_ssb_connect(tf_ssb_t* ssb, const char* host, int port, const uint8_t* key); + +/** +** Establish an SHS connection with a host by string address. +** @param ssb The SSB instance. +** @param address The address. +*/ void tf_ssb_connect_str(tf_ssb_t* ssb, const char* address); + +/** +** Begin listening for SHS connections on the given port. +** @param ssb The SSB instance. +** @param port The port number. +*/ void tf_ssb_server_open(tf_ssb_t* ssb, int port); + +/** +** Stop listening for SHS connections. +** @param ssb The SSB instance. +*/ void tf_ssb_server_close(tf_ssb_t* ssb); +/** +** Close all active SHS connections. +** @param ssb The SSB instance. +*/ void tf_ssb_close_all(tf_ssb_t* ssb); + +/** +** Send a graceful close message to all active SHS connections. +** @param ssb The SSB instance. +*/ void tf_ssb_send_close(tf_ssb_t* ssb); +/** +** Convert an SSB identity from string to binary. +** @param[out] bin A buffer to receive the binary identity. +** @param str The string identity. +** @return True if the conversion was successful. +*/ bool tf_ssb_id_str_to_bin(uint8_t* bin, const char* str); + +/** +** Convert an SSB identity from binary to string. +** @param[out] str A buffer to receive the identity string. +** @param str_size The size of the string buffer. +** @param bin The binary identity. +** @return True if the conversion was successful. +*/ bool tf_ssb_id_bin_to_str(char* str, size_t str_size, const uint8_t* bin); +/** +** Verify a message's signature and remove the signature if successful. +** @param context A JS context. +** @param val The message. +** @param[out] out_id A buffer to receive the message's identity. +** @param out_id_size The size of out_id. +** @param[out] out_signature A buffer to receive the message's signature. +** @param out_signature_size The size of out_signature. +** @param[out] out_sequence_before_author A flag describing the order of the sequence and author fields. +** @return True if the signature is valid and was successfully extracted. +*/ bool tf_ssb_verify_and_strip_signature( JSContext* context, JSValue val, char* out_id, size_t out_id_size, char* out_signature, size_t out_signature_size, bool* out_sequence_before_author); + +/** +** Determine the message identifier. +** @param context A JS context. +** @param message The message. +** @param[out] out_id A buffer to receive the identifier. +** @param out_id_size The size of out_id. +*/ void tf_ssb_calculate_message_id(JSContext* context, JSValue message, char* out_id, size_t out_id_size); + +/** +** A function called on completion of tf_ssb_verify_strip_and_store_message(). +** @param id The stored message identifier. +** @param verified True if the message was verified successfully. +** @param is_new True if the message was newly added to the database. +** @param user_data The user data. +*/ typedef void(tf_ssb_verify_strip_store_callback_t)(const char* id, bool verified, bool is_new, void* user_data); + +/** +** Verify a message's signature, remove the signature, and store the message in the database. +** @param ssb The SSB instance. +** @param value The message. +** @param callback A callback called when the operation completed. +** @param user_data User data to pass to the callback. +*/ void tf_ssb_verify_strip_and_store_message(tf_ssb_t* ssb, JSValue value, tf_ssb_verify_strip_store_callback_t* callback, void* user_data); +/** +** Check if a connection is an outgoing connection. +** @param connection The connection. +** @return True if the connection is outgoing. +*/ bool tf_ssb_connection_is_client(tf_ssb_connection_t* connection); + +/** +** Get the hostname of the remote end of a connection. +** @param connection The connection. +** @return The hostname or address. +*/ const char* tf_ssb_connection_get_host(tf_ssb_connection_t* connection); + +/** +** Get a connection's remote port number. +** @param connection The connection. +** @return The port number. +*/ int tf_ssb_connection_get_port(tf_ssb_connection_t* connection); + +/** +** If a connection is a tunnel, get its parent connection. +** @param connection The connection. +** @return The parent connection if the connection is tunneled or NULL. +*/ tf_ssb_connection_t* tf_ssb_connection_get_tunnel(tf_ssb_connection_t* connection); + +/** +** Get a connection's SSB instance. +** @param connection The connection. +** @return The SSB instance. +*/ tf_ssb_t* tf_ssb_connection_get_ssb(tf_ssb_connection_t* connection); + +/** +** Get a connection's JS context. +** @param connection The connection. +** @return The JS context. +*/ JSContext* tf_ssb_connection_get_context(tf_ssb_connection_t* connection); -sqlite3* tf_ssb_connection_get_db(tf_ssb_connection_t* connection); -void tf_ssb_connection_close(tf_ssb_connection_t* connect); + +/** +** Close a connection. +** @param connection The connection. +*/ +void tf_ssb_connection_close(tf_ssb_connection_t* connection); + +/** +** Check whether a connection is connected. +** @param connection The connection. +** @return True if the connection is alive. +*/ bool tf_ssb_connection_is_connected(tf_ssb_connection_t* connection); +/** +** Get the next outgoing request number for a connection. +** @param connection The connection. +** @return The next request number. +*/ int32_t tf_ssb_connection_next_request_number(tf_ssb_connection_t* connection); +/** +** Get an active connection by its identity. +** @param ssb The SSB instance. +** @param id The SSB identity. +** @return The connection if found or NULL. +*/ tf_ssb_connection_t* tf_ssb_connection_get(tf_ssb_t* ssb, const char* id); + +/** +** Get the SSB identity of a connection. +** @param connection The connection. +** @param[out] out_id A buffer to be populated with the identity. +** @param out_id_size The size of out_id. +** @return True if the identity was retrieved. +*/ bool tf_ssb_connection_get_id(tf_ssb_connection_t* connection, char* out_id, size_t out_id_size); + +/** +** Get the JS object representing a connection. +** @param connection The connection. +** @return The object. +*/ JSValue tf_ssb_connection_get_object(tf_ssb_connection_t* connection); -/* Callbacks. */ +/** +** A callback called when a callback is cleaned up. +** @param ssb The SSB instance. +** @param user_data User data. +*/ typedef void(tf_ssb_callback_cleanup_t)(tf_ssb_t* ssb, void* user_data); + +/** +** A callback called when the connection list changes. +** @param ssb The SSB instance. +** @param change The type of change. +** @param connection The connection that changed. +** @param user_data User data. +*/ typedef void(tf_ssb_connections_changed_callback_t)(tf_ssb_t* ssb, tf_ssb_change_t change, tf_ssb_connection_t* connection, void* user_data); + +/** +** Register a callback when the connection list changes. +** @param ssb The SSB instance. +** @param callback The callback to register. +** @param cleanup The cleanup callback to register. +** @param user_data User data to pass to the callbacks. +*/ void tf_ssb_add_connections_changed_callback(tf_ssb_t* ssb, tf_ssb_connections_changed_callback_t* callback, tf_ssb_callback_cleanup_t* cleanup, void* user_data); + +/** +** Remove a callback when the connection list changes. +** @param ssb The SSB instance. +** @param callback The callback. +** @param user_data The user data registered with the callback. +*/ void tf_ssb_remove_connections_changed_callback(tf_ssb_t* ssb, tf_ssb_connections_changed_callback_t* callback, void* user_data); typedef void(tf_ssb_broadcasts_changed_callback_t)(tf_ssb_t* ssb, void* user_data); diff --git a/src/ssb.import.h b/src/ssb.import.h index 06d41949..ed311f95 100644 --- a/src/ssb.import.h +++ b/src/ssb.import.h @@ -8,9 +8,24 @@ ** @{ */ +/** An SSB instance. */ typedef struct _tf_ssb_t tf_ssb_t; +/** +** Import apps in a directory to a user's account. +** @param ssb The SSB instance. +** @param user The username. +** @param path The on-disk path of the apps. +*/ void tf_ssb_import(tf_ssb_t* ssb, const char* user, const char* path); + +/** +** Import apps from a zip file to a user's account. +** @param ssb The SSB instance. +** @param zip_path The path to the zip file on disk. +** @param user The user into whose account the apps will be imported. +** @param path The path in the zip to the apps. +*/ void tf_ssb_import_from_zip(tf_ssb_t* ssb, const char* zip_path, const char* user, const char* path); /** @} */ diff --git a/src/ssb.js.h b/src/ssb.js.h index 72ce881c..eb6ba31a 100644 --- a/src/ssb.js.h +++ b/src/ssb.js.h @@ -6,9 +6,14 @@ ** @{ */ +/** A JS context. */ typedef struct JSContext JSContext; +/** An SSB instance. */ typedef struct _tf_ssb_t tf_ssb_t; +/** +** Register the SSB script interface. +*/ void tf_ssb_register(JSContext* context, tf_ssb_t* ssb); /** @} */ diff --git a/src/ssb.rpc.h b/src/ssb.rpc.h index 1077513a..45d84632 100644 --- a/src/ssb.rpc.h +++ b/src/ssb.rpc.h @@ -7,9 +7,19 @@ ** @{ */ +/** An SSB instance. */ typedef struct _tf_ssb_t tf_ssb_t; +/** +** Register standard muxrpc callbacks. +** @param ssb The SSB instance. +*/ void tf_ssb_rpc_register(tf_ssb_t* ssb); + +/** +** Start periodic SSB maintenance tasks. +** @param ssb The SSB instance. +*/ void tf_ssb_rpc_start_periodic(tf_ssb_t* ssb); /** @} */ diff --git a/src/ssb.tests.h b/src/ssb.tests.h index 8d3eac3e..d9d31c36 100644 --- a/src/ssb.tests.h +++ b/src/ssb.tests.h @@ -6,13 +6,45 @@ ** @{ */ +/** +** Options to control how tests are run. +*/ typedef struct _tf_test_options_t tf_test_options_t; +/** +** Test converting SSB identities. +** @param options The test options. +*/ void tf_ssb_test_id_conversion(const tf_test_options_t* options); + +/** +** Test SSB connections and replication. +** @param options The test options. +*/ void tf_ssb_test_ssb(const tf_test_options_t* options); + +/** +** Test SSB following calculations. +** @param options The test options. +*/ void tf_ssb_test_following(const tf_test_options_t* options); + +/** +** Test SSB rooms. +** @param options The test options. +*/ void tf_ssb_test_rooms(const tf_test_options_t* options); + +/** +** Benchmark SSB replication performacnce. +** @param options The test options. +*/ void tf_ssb_test_bench(const tf_test_options_t* options); + +/** +** Test communicating with go-ssb-room. +** @param options The test options. +*/ void tf_ssb_test_go_ssb_room(const tf_test_options_t* options); /** @} */