c-libp2p/include/libp2p/net/stream.h
2017-11-30 14:32:36 -05:00

180 lines
4.8 KiB
C

#pragma once
#include <pthread.h>
#include <stdint.h>
/**
* Encapsulates a message that (was/will be) sent
* across a stream
*/
struct StreamMessage {
uint8_t* data;
size_t data_size;
int error_number;
};
/***
* Create a new StreamMessage struct
* @returns a StreamMessage struct
*/
struct StreamMessage* libp2p_stream_message_new();
/**
* free resources of a StreamMessage struct
* @param msg the StreamMessage to free
*/
void libp2p_stream_message_free(struct StreamMessage* msg);
/***
* Make a copy of a message
* @param original the original message
* @returns a StreamMessage that is a copy of the original
*/
struct StreamMessage* libp2p_stream_message_copy(const struct StreamMessage* original);
/**
* This is a context struct for a basic IP connection
*/
struct ConnectionContext {
int socket_descriptor;
unsigned long long last_comm_epoch;
struct SessionContext* session_context;
};
/**
* The different types of protocols
*/
enum stream_type {
STREAM_TYPE_UNKNOWN = 0x0,
STREAM_TYPE_MULTISTREAM = 0x1,
STREAM_TYPE_SECIO = 0x2,
STREAM_TYPE_KADEMLIA = 0x3,
STREAM_TYPE_IDENTIFY = 0x4,
STREAM_TYPE_YAMUX = 0x5,
STREAM_TYPE_JOURNAL = 0x6,
STREAM_TYPE_RAW = 0x7
};
/**
* An interface in front of various streams
*/
struct Stream {
/**
* A generic socket descriptor
*/
struct MultiAddress* address; // helps identify who is on the other end
pthread_mutex_t* socket_mutex; // only 1 transmission at a time
struct Stream* parent_stream; // what stream wraps this stream
int channel; // the channel (for multiplexing streams)
enum stream_type stream_type;
/**
* A generic place to store implementation-specific context items
*/
void* stream_context;
/**
* Reads from the stream
* @param stream the stream context (usually a SessionContext pointer)
* @param message where to put the incoming message (will be allocated)
* @param timeout_secs number of seconds before a timeout
* @returns true(1) on success, false(0) otherwise
*/
int (*read)(void* stream_context, struct StreamMessage** message, int timeout_secs);
/**
* Reads a certain amount of bytes directly from the stream
* @param stream_context the context
* @param buffer where to put the results
* @param buffer_size the number of bytes to read
* @param timeout_secs number of seconds before a timeout
* @returns number of bytes read, or -1 on error
*/
int (*read_raw)(void* stream_context, uint8_t* buffer, int buffer_size, int timeout_secs);
/**
* Writes to a stream
* @param stream the stream context (usually a SessionContext pointer)
* @param buffer what to write
* @returns true(1) on success, false(0) otherwise
*/
int (*write)(void* stream_context, struct StreamMessage* buffer);
/**
* Closes a stream
*
* NOTE: This is also responsible for deallocating the Stream struct
* @param stream the stream
* @returns true(1) on success, otherwise false(0)
*/
int (*close)(struct Stream* stream);
/***
* Checks to see if something is waiting on the stream
*
* @param stream the stream context
* @returns true(1) if something is waiting, false(0) if not, -1 on error
*/
int (*peek)(void* stream_context);
/**
* Handle a stream upgrade
* @param stream the current stream
* @param new_stream the newly created stream
*/
int (*handle_upgrade)(struct Stream* stream, struct Stream* new_stream);
/***
* Negotiate this protocol using the parent stream
* @param parent_stream the connection to use
* @returns a new Stream, or NULL on error
*/
struct Stream* (*negotiate)(struct Stream* parent_stream);
/****
* A message has been received, and needs to be handled
* @param stream the stream that has the message waiting
* @returns number of bytes processed
*/
int (*bytes_waiting)(struct Stream* stream);
};
struct Stream* libp2p_stream_new();
void libp2p_stream_free(struct Stream* stream);
/***
* Attempt to lock a stream for personal use. Does not block.
* @param stream the stream to lock
* @returns true(1) on success, false(0) otherwise
*/
int libp2p_stream_try_lock(struct Stream* stream);
/***
* Attempt to lock a stream for personal use. Blocks until the lock is acquired
* @param stream the stream to lock
* @returns true(1) on success, false(0) otherwise
*/
int libp2p_stream_lock(struct Stream* stream);
/***
* Attempt to unlock the mutex for this stream
* @param stream the stream to unlock
* @returns true(1) on success, false(0) otherwise
*/
int libp2p_stream_unlock(struct Stream* stream);
/***
* Determine if this stream is open
* @param stream the stream to check
* @returns true(1) if the stream is open, false otherwise
*/
int libp2p_stream_is_open(struct Stream* stream);
/**
* Look for the latest stream
* (properly handles both raw streams and yamux streams)
* @param in the incoming stream
* @returns the latest child stream
*/
struct Stream* libp2p_stream_get_latest_stream(struct Stream* in);