Skip to main content

Crate rustp2p_c_ffi

Crate rustp2p_c_ffi 

Source
Expand description

§rustp2p-c-ffi - C FFI Bindings for rustp2p

This crate provides C-compatible Foreign Function Interface (FFI) bindings for the rustp2p library, enabling integration with C, C++, and other languages that support C FFI.

§Features

  • C-Compatible API: Simple, pointer-based API for C/C++ integration
  • Builder Pattern: Fluent API for configuration
  • Error Handling: Clear error codes for all operations
  • Memory Safety: Proper ownership and cleanup functions
  • Cross-Platform: Works on Windows, Linux, and macOS

§Building

This crate produces both a static library and a dynamic library:

cargo build --release

Output files:

  • librustp2p_c_ffi.a / rustp2p_c_ffi.lib (static)
  • librustp2p_c_ffi.so / rustp2p_c_ffi.dll / librustp2p_c_ffi.dylib (dynamic)

§C Usage Example

§Basic Setup

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Create and configure a node
Rustp2pBuilder* builder = rustp2p_builder_new();
rustp2p_builder_node_id(builder, "10.0.0.1");
rustp2p_builder_udp_port(builder, 8080);
rustp2p_builder_group_code(builder, "12345");

// Build the endpoint
Rustp2pEndpoint* endpoint = rustp2p_builder_build(builder);
if (!endpoint) {
    fprintf(stderr, "Failed to build endpoint\n");
    return -1;
}

§Sending Data

const char* message = "Hello, peer!";
int result = rustp2p_endpoint_send_to(
    endpoint,
    "10.0.0.2",
    (const uint8_t*)message,
    strlen(message)
);

if (result == RUSTP2P_OK) {
    printf("Message sent successfully\n");
}

§Receiving Data

// Blocking receive
Rustp2pRecvData* recv_data = rustp2p_endpoint_recv_from(endpoint);
if (recv_data) {
    const uint8_t* data;
    size_t len;
    rustp2p_recv_data_get_payload(recv_data, &data, &len);
     
    char src_id[16];
    rustp2p_recv_data_get_src_id(recv_data, src_id, sizeof(src_id));
     
    printf("Received %zu bytes from %s\n", len, src_id);
     
    rustp2p_recv_data_free(recv_data);
}

§Cleanup

rustp2p_endpoint_free(endpoint);

§Error Codes

The library uses the following error codes:

  • RUSTP2P_OK (0): Success
  • RUSTP2P_ERROR (-1): General error
  • RUSTP2P_ERROR_NULL_PTR (-2): NULL pointer provided
  • RUSTP2P_ERROR_INVALID_STR (-3): Invalid string
  • RUSTP2P_ERROR_INVALID_IP (-4): Invalid IP address
  • RUSTP2P_ERROR_BUILD_FAILED (-5): Failed to build endpoint
  • RUSTP2P_ERROR_WOULD_BLOCK (-6): Operation would block
  • RUSTP2P_ERROR_EOF (-7): End of file / connection closed

§Complete C Example

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>

void* receive_thread(void* arg) {
    Rustp2pEndpoint* endpoint = (Rustp2pEndpoint*)arg;
     
    while (1) {
        Rustp2pRecvData* recv_data = rustp2p_endpoint_recv_from(endpoint);
        if (!recv_data) {
            break;
        }
         
        const uint8_t* data;
        size_t len;
        rustp2p_recv_data_get_payload(recv_data, &data, &len);
         
        char src_id[16];
        rustp2p_recv_data_get_src_id(recv_data, src_id, sizeof(src_id));
         
        printf("Received %zu bytes from %s: %.*s\n", len, src_id, (int)len, data);
         
        rustp2p_recv_data_free(recv_data);
    }
     
    return NULL;
}

int main() {
    // Create builder
    Rustp2pBuilder* builder = rustp2p_builder_new();
    if (!builder) {
        return -1;
    }
     
    // Configure
    rustp2p_builder_node_id(builder, "10.0.0.1");
    rustp2p_builder_udp_port(builder, 8080);
    rustp2p_builder_tcp_port(builder, 8080);
    rustp2p_builder_group_code(builder, "12345");
    rustp2p_builder_add_peer(builder, "udp://192.168.1.100:9090");
     
    // Build endpoint
    Rustp2pEndpoint* endpoint = rustp2p_builder_build(builder);
    if (!endpoint) {
        fprintf(stderr, "Failed to build endpoint\n");
        return -1;
    }
     
    // Start receive thread
    pthread_t thread;
    pthread_create(&thread, NULL, receive_thread, endpoint);
     
    // Send messages
    const char* message = "Hello from C!";
    rustp2p_endpoint_send_to(endpoint, "10.0.0.2",
                             (const uint8_t*)message, strlen(message));
     
    // Wait for thread
    pthread_join(thread, NULL);
     
    // Cleanup
    rustp2p_endpoint_free(endpoint);
     
    return 0;
}

§C++ Integration

For C++ projects, wrap the C API in RAII classes:

class Rustp2pEndpointWrapper {
    Rustp2pEndpoint* endpoint_;
public:
    Rustp2pEndpointWrapper(Rustp2pEndpoint* ep) : endpoint_(ep) {}
    ~Rustp2pEndpointWrapper() {
        if (endpoint_) {
            rustp2p_endpoint_free(endpoint_);
        }
    }
     
    // Prevent copying
    Rustp2pEndpointWrapper(const Rustp2pEndpointWrapper&) = delete;
    Rustp2pEndpointWrapper& operator=(const Rustp2pEndpointWrapper&) = delete;
     
    Rustp2pEndpoint* get() { return endpoint_; }
};

§JavaScript/TypeScript Integration

See JAVASCRIPT.md for details on using these bindings with Node.js via node-ffi-napi.

§Thread Safety

  • All functions are thread-safe
  • Multiple threads can call send/receive operations simultaneously
  • The Tokio runtime is managed internally

§Memory Management

  • Always call the corresponding _free function for allocated resources
  • Do not use pointers after calling _free
  • Received data pointers are valid only until rustp2p_recv_data_free is called

§See Also

Structs§

Rustp2pBuilder
Builder handle for configuring a rustp2p endpoint.
Rustp2pEndpoint
Endpoint handle for sending and receiving P2P data.
Rustp2pRecvData
Received data handle containing both payload and metadata.

Constants§

RUSTP2P_ERROR
General error occurred.
RUSTP2P_ERROR_BUILD_FAILED
Failed to build endpoint (e.g., port in use, invalid config).
RUSTP2P_ERROR_EOF
End of file / connection closed.
RUSTP2P_ERROR_INVALID_IP
Invalid IP address format.
RUSTP2P_ERROR_INVALID_STR
Invalid string format or encoding.
RUSTP2P_ERROR_NULL_PTR
NULL pointer was provided where a valid pointer was expected.
RUSTP2P_ERROR_WOULD_BLOCK
Operation would block (for non-blocking operations).
RUSTP2P_OK
Operation completed successfully.

Functions§

rustp2p_builder_add_peer
Add a peer address (e.g., “udp://127.0.0.1:9090” or “tcp://192.168.1.1:8080”)
rustp2p_builder_build
Build the endpoint
rustp2p_builder_encryption
Set encryption algorithm algorithm: 0 = AesGcm, 1 = ChaCha20Poly1305 (if available) password: the encryption password
rustp2p_builder_free
Free/destroy the builder
rustp2p_builder_group_code
Set group code from string (e.g., “mygroup” or “12345”)
rustp2p_builder_new
Create a new builder
rustp2p_builder_node_id
Set node ID from IPv4 address string (e.g., “10.0.0.1”)
rustp2p_builder_tcp_port
Set TCP port
rustp2p_builder_udp_port
Set UDP port
rustp2p_endpoint_free
Free/destroy the endpoint
rustp2p_endpoint_recv_from
Receive data from peers (blocking)
rustp2p_endpoint_send_to
Send data to a peer
rustp2p_endpoint_try_recv_from
Try to receive data from peers (non-blocking) Returns pointer to received data structure, or NULL if no data available or on error Caller must free the returned pointer with rustp2p_recv_data_free
rustp2p_endpoint_try_send_to
Try to send data to a peer (non-blocking)
rustp2p_recv_data_free
Free received data
rustp2p_recv_data_get_dest_id
Get destination node ID from received data as IPv4 string
rustp2p_recv_data_get_payload
Get payload data from received data out_data: output pointer to data (borrowed, don’t free) out_len: output length
rustp2p_recv_data_get_src_id
Get source node ID from received data as IPv4 string buffer: output buffer for IP string buffer_len: size of buffer (should be at least 16 bytes for “xxx.xxx.xxx.xxx\0”)
rustp2p_recv_data_is_relay
Check if the received data was relayed