2017-02-22 15:55:39 +00:00
|
|
|
#pragma once
|
|
|
|
|
2017-10-12 17:37:40 +00:00
|
|
|
#include <pthread.h>
|
2017-10-23 23:03:38 +00:00
|
|
|
#include <stdint.h>
|
2017-10-12 17:37:40 +00:00
|
|
|
|
2017-10-23 14:01:03 +00:00
|
|
|
/**
|
|
|
|
* 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);
|
|
|
|
|
2017-11-19 18:37:03 +00:00
|
|
|
/***
|
|
|
|
* 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);
|
2017-10-23 14:01:03 +00:00
|
|
|
|
2017-10-23 20:21:50 +00:00
|
|
|
/**
|
|
|
|
* This is a context struct for a basic IP connection
|
|
|
|
*/
|
|
|
|
struct ConnectionContext {
|
|
|
|
int socket_descriptor;
|
2017-10-25 17:28:53 +00:00
|
|
|
unsigned long long last_comm_epoch;
|
2017-10-23 20:21:50 +00:00
|
|
|
struct SessionContext* session_context;
|
|
|
|
};
|
|
|
|
|
2017-11-19 18:37:03 +00:00
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
};
|
2017-10-23 20:21:50 +00:00
|
|
|
|
2017-02-22 15:55:39 +00:00
|
|
|
/**
|
|
|
|
* An interface in front of various streams
|
|
|
|
*/
|
|
|
|
struct Stream {
|
|
|
|
/**
|
|
|
|
* A generic socket descriptor
|
|
|
|
*/
|
2017-10-23 20:21:50 +00:00
|
|
|
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
|
2017-11-08 15:51:43 +00:00
|
|
|
int channel; // the channel (for multiplexing streams)
|
2017-11-19 18:37:03 +00:00
|
|
|
enum stream_type stream_type;
|
2017-11-08 15:51:43 +00:00
|
|
|
|
2017-10-23 20:21:50 +00:00
|
|
|
/**
|
|
|
|
* A generic place to store implementation-specific context items
|
|
|
|
*/
|
|
|
|
void* stream_context;
|
2017-02-22 15:55:39 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Reads from the stream
|
2017-03-30 18:58:53 +00:00
|
|
|
* @param stream the stream context (usually a SessionContext pointer)
|
2017-10-23 14:01:03 +00:00
|
|
|
* @param message where to put the incoming message (will be allocated)
|
2017-04-17 19:03:27 +00:00
|
|
|
* @param timeout_secs number of seconds before a timeout
|
2017-02-22 15:55:39 +00:00
|
|
|
* @returns true(1) on success, false(0) otherwise
|
|
|
|
*/
|
2017-10-23 14:01:03 +00:00
|
|
|
int (*read)(void* stream_context, struct StreamMessage** message, int timeout_secs);
|
2017-02-22 15:55:39 +00:00
|
|
|
|
2017-10-23 20:21:50 +00:00
|
|
|
/**
|
|
|
|
* 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);
|
|
|
|
|
2017-02-22 15:55:39 +00:00
|
|
|
/**
|
|
|
|
* Writes to a stream
|
2017-08-30 16:09:28 +00:00
|
|
|
* @param stream the stream context (usually a SessionContext pointer)
|
2017-02-22 15:55:39 +00:00
|
|
|
* @param buffer what to write
|
|
|
|
* @returns true(1) on success, false(0) otherwise
|
|
|
|
*/
|
2017-10-23 14:47:54 +00:00
|
|
|
int (*write)(void* stream_context, struct StreamMessage* buffer);
|
2017-02-22 15:55:39 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Closes a stream
|
2017-07-27 19:32:42 +00:00
|
|
|
*
|
|
|
|
* NOTE: This is also responsible for deallocating the Stream struct
|
2017-11-08 15:51:43 +00:00
|
|
|
* @param stream the stream
|
2017-02-22 15:55:39 +00:00
|
|
|
* @returns true(1) on success, otherwise false(0)
|
|
|
|
*/
|
2017-11-08 15:51:43 +00:00
|
|
|
int (*close)(struct Stream* stream);
|
2017-08-03 16:15:40 +00:00
|
|
|
|
|
|
|
/***
|
|
|
|
* Checks to see if something is waiting on the stream
|
|
|
|
*
|
|
|
|
* @param stream the stream context
|
2017-11-02 18:20:40 +00:00
|
|
|
* @returns true(1) if something is waiting, false(0) if not, -1 on error
|
2017-08-03 16:15:40 +00:00
|
|
|
*/
|
|
|
|
int (*peek)(void* stream_context);
|
2017-11-08 15:51:43 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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);
|
2017-11-19 18:37:03 +00:00
|
|
|
|
|
|
|
/***
|
|
|
|
* 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);
|
2017-11-29 15:57:48 +00:00
|
|
|
|
|
|
|
/****
|
|
|
|
* A message has been received, and needs to be handled
|
2017-11-30 19:32:36 +00:00
|
|
|
* @param stream the stream that has the message waiting
|
|
|
|
* @returns number of bytes processed
|
2017-11-29 15:57:48 +00:00
|
|
|
*/
|
2017-11-30 19:32:36 +00:00
|
|
|
int (*bytes_waiting)(struct Stream* stream);
|
2017-02-22 15:55:39 +00:00
|
|
|
};
|
2017-10-12 17:37:40 +00:00
|
|
|
|
2017-10-23 23:03:38 +00:00
|
|
|
struct Stream* libp2p_stream_new();
|
|
|
|
|
|
|
|
void libp2p_stream_free(struct Stream* stream);
|
|
|
|
|
2017-10-12 17:37:40 +00:00
|
|
|
/***
|
|
|
|
* 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);
|
2017-11-30 19:32:36 +00:00
|
|
|
|
|
|
|
/***
|
|
|
|
* 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);
|