... | @@ -221,3 +221,730 @@ static int cb_auth_connect(void *arg, const char* connecting_ip, uint16_t connec |
... | @@ -221,3 +221,730 @@ static int cb_auth_connect(void *arg, const char* connecting_ip, uint16_t connec |
|
}
|
|
}
|
|
```
|
|
```
|
|
___
|
|
___
|
|
|
|
#####
|
|
|
|
int rist_oob_read(struct rist_ctx *ctx, const struct rist_oob_block **oob_block);
|
|
|
|
|
|
|
|
Parameters:
|
|
|
|
- ctx RIST context
|
|
|
|
- [out] oob_block pointer to the rist_oob_block structure
|
|
|
|
|
|
|
|
Returns: return 0 on success, -1 in case of error.
|
|
|
|
|
|
|
|
Notes: Reads out-of-band data; use this API to read out-of-band data from an internal fifo queue instead of the callback
|
|
|
|
___
|
|
|
|
##### int rist_oob_callback_set(struct rist_ctx *ctx, int (*oob_callback)(void *arg, const struct rist_oob_block *oob_block), void *arg);
|
|
|
|
|
|
|
|
Parameters:
|
|
|
|
- ctx RIST context
|
|
|
|
- oob_callback A pointer to the function that will be called when out-of-band data comes in (NULL function pointer is valid)
|
|
|
|
- arg is an the extra argument passed to the oob_callback
|
|
|
|
|
|
|
|
Returns: return 0 on success, -1 on error
|
|
|
|
|
|
|
|
Notes: Enable out-of-band data channel; call after receiver initialization to enable out-of-band data.
|
|
|
|
|
|
|
|
Example: The code below (from ristsender.c) shows an attempt to set up the callback, providing the context and the out-of-band datastructure.
|
|
|
|
|
|
|
|
```
|
|
|
|
if (rist_oob_callback_set(ctx, cb_recv_oob, ctx) == -1) {
|
|
|
|
rist_log(logging_settings, RIST_LOG_ERROR, "Could not enable out-of-band data\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
```
|
|
|
|
___
|
|
|
|
##### int rist_auth_handler_set(struct rist_ctx *ctx, int (*connect_cb)(void *arg, const char* conn_ip, uint16_t conn_port, const char* local_ip, uint16_t local_port, struct rist_peer *peer), int (*disconn_cb)(void *arg, struct rist_peer *peer), void *arg);
|
|
|
|
|
|
|
|
Parameters:
|
|
|
|
- ctx RIST context
|
|
|
|
- connect_cb A pointer to the function that will be called when a new peer connects. Return 0 or -1 to authorize or decline (NULL function pointer is valid)
|
|
|
|
- disconn_cb A pointer to the function that will be called when a new peer is marked as dead (NULL function pointer is valid)
|
|
|
|
- arg is an the extra argument passed to the conn_cb and disconn_cb
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
|
|
Notes: Assign dynamic authentication handler. Whenever a new peer is connected, @a connect_cb is called.. Whenever a new peer is disconnected, @a disconn_cb is called.
|
|
|
|
|
|
|
|
Example: The code below (from ristsender.c) shows the authorization handler being set up with the context and the connect/disconnect objects.
|
|
|
|
|
|
|
|
```
|
|
|
|
int rist;
|
|
|
|
...
|
|
|
|
rist = rist_auth_handler_set(ctx, cb_auth_connect, cb_auth_disconnect, ctx);
|
|
|
|
```
|
|
|
|
___
|
|
|
|
##### int rist_peer_create(struct rist_ctx *ctx, struct rist_peer **peer, const struct rist_peer_config *config);
|
|
|
|
|
|
|
|
Parameters:
|
|
|
|
- ctx RIST context
|
|
|
|
- [out] peer Store the new peer pointer
|
|
|
|
- config a pointer to the struct rist_peer_config, which contains the configuration parameters for the peer endpoint.
|
|
|
|
|
|
|
|
Returns: return 0 on success, -1 in case of error.
|
|
|
|
|
|
|
|
Notes: Add a peer connector to the existing sender. One sender can send data to multiple peers.
|
|
|
|
|
|
|
|
Example: The code below (from ristsender.c) shows a peer being created by passing the context along with the peer structure and configuration options.
|
|
|
|
|
|
|
|
```
|
|
|
|
struct rist_peer *peer;
|
|
|
|
if (rist_peer_create(ctx, &peer, peer_config_link) == -1) {
|
|
|
|
rist_log(logging_settings, RIST_LOG_ERROR, "Could not add peer connector to sender #%i\n", (int)(i + 1));
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
```
|
|
|
|
___
|
|
|
|
##### int rist_peer_destroy(struct rist_ctx *ctx, struct rist_peer *peer);
|
|
|
|
|
|
|
|
Parameters:
|
|
|
|
- ctx RIST context
|
|
|
|
- peer a pointer to the struct rist_peer, which points to the peer endpoint.
|
|
|
|
|
|
|
|
Returns: return 0 on success, -1 in case of error.
|
|
|
|
|
|
|
|
Notes: Remove a peer connector to the existing sender.
|
|
|
|
___
|
|
|
|
Parameters:
|
|
|
|
- ctx RIST context
|
|
|
|
- t max jitter in ms
|
|
|
|
|
|
|
|
Returns: return 0 on success, -1 on error
|
|
|
|
|
|
|
|
Notes: Set max jitter
|
|
|
|
___
|
|
|
|
##### int rist_start(struct rist_ctx *ctx);
|
|
|
|
|
|
|
|
Parameters: ctx RIST context
|
|
|
|
|
|
|
|
Returns: return 0 on success, -1 in case of error.
|
|
|
|
|
|
|
|
Notes: Kickstart a pre-configured sender. After all the peers have been added, this function triggers the sender to start
|
|
|
|
|
|
|
|
Example: The code below, (from ristsender.c),takes place after the parameters and configurations have been parsed and the startup notifications logged; in other words, it shows the moment at which the RIST connection "goes to work."
|
|
|
|
|
|
|
|
```
|
|
|
|
if (rist_start(ctx) == -1) {
|
|
|
|
rist_log(logging_settings, RIST_LOG_ERROR, "Could not start rist sender\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
```
|
|
|
|
___
|
|
|
|
##### int rist_destroy(struct rist_ctx *ctx);
|
|
|
|
|
|
|
|
Parameters: ctx RIST context
|
|
|
|
|
|
|
|
Returns: return 0 on success, -1 on error
|
|
|
|
|
|
|
|
Notes: Destroy RIST sender/instance
|
|
|
|
|
|
|
|
Example: The code below, (from ristsender.c), takes place when the signalReceived variable becomes 0, indicating that the connection was dropped. It closes the sockets and destroys the rist context.
|
|
|
|
|
|
|
|
```
|
|
|
|
// Shut down sockets and rist contexts
|
|
|
|
evsocket_destroy(evctx);
|
|
|
|
rist_destroy(ctx);
|
|
|
|
```
|
|
|
|
___
|
|
|
|
#####
|
|
|
|
int rist_parse_address(const char *url, const struct rist_peer_config **peer_config);
|
|
|
|
|
|
|
|
Parameters:
|
|
|
|
- url a pointer to a url to be parsed, for example "rist://myserver.net:1234?buffer=100&cname=hello"
|
|
|
|
[out] peer_config a pointer to a the rist_peer_config structure (NULL is allowed).
|
|
|
|
- Note: when passing NULL, the library will allocate a new rist_peer_config structure with the latest default values and it expects the application to free it when it is done using it. * @return 0 on success or non-zero on error. The value returned is actually the number of parameters that are valid
|
|
|
|
|
|
|
|
Returns: return 0 on success or non-zero on error. The value returned is actually the number of parameters that are valid
|
|
|
|
|
|
|
|
Notes: Parses url for peer config data (encryption, compression, etc). Use this API to parse a generic URL string and turn it into a meaninful peer_config structure
|
|
|
|
___
|
|
|
|
#####
|
|
|
|
int rist_stats_callback_set(struct rist_ctx *ctx, int statsinterval, int (*stats_cb)(void *arg, const struct rist_stats *stats_container), void *arg);
|
|
|
|
|
|
|
|
Parameters:
|
|
|
|
- ctx RIST context
|
|
|
|
- statsinterval interval between stats reporting
|
|
|
|
- stats_cb Callback function that will be called. The json char pointer must be free()'d when you are finished.
|
|
|
|
- arg extra arguments for callback function
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
|
|
Notes: Set callback for receiving stats structs
|
|
|
|
|
|
|
|
Example: The code below, (from ristsender.c), sets up the callback function for the stats with the context, the interval for reporting and the stats callback structure.
|
|
|
|
|
|
|
|
```
|
|
|
|
if (rist_stats_callback_set(ctx, statsinterval, cb_stats, NULL) == -1) {
|
|
|
|
rist_log(logging_settings, RIST_LOG_ERROR, "Could not enable stats callback\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
```
|
|
|
|
___
|
|
|
|
##### int rist_stats_free(const struct rist_stats *stats_container);
|
|
|
|
|
|
|
|
Parameters:
|
|
|
|
|
|
|
|
Returns: return 0 on success or non-zero on error
|
|
|
|
|
|
|
|
Notes: Free the rist_stats structure memory allocation
|
|
|
|
|
|
|
|
Example: The code below, (from ristsender.c), shows the stats callback. After it has logged the desired stats, it then calls rist_stats_free to clear the previous stats.
|
|
|
|
|
|
|
|
```
|
|
|
|
static int cb_stats(void *arg, const struct rist_stats *stats_container) {
|
|
|
|
(void)arg;
|
|
|
|
rist_log(logging_settings, RIST_LOG_INFO, "%s\n\n", stats_container->stats_json);
|
|
|
|
rist_stats_free(stats_container);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
```
|
|
|
|
___
|
|
|
|
##### const char *librist_version(void);
|
|
|
|
|
|
|
|
Parameters:
|
|
|
|
|
|
|
|
Returns: return String representing the version of libRIST
|
|
|
|
|
|
|
|
Notes: Get the version of libRIS
|
|
|
|
___
|
|
|
|
**Selected struct definitions**
|
|
|
|
|
|
|
|
You will find these in headers.h. We place a few key structs here for convenience.
|
|
|
|
|
|
|
|
The rist_data_block's most important component is the payload. The sequence number, timestamp and other descriptors help to identify its proper place.
|
|
|
|
|
|
|
|
```
|
|
|
|
struct rist_data_block
|
|
|
|
{
|
|
|
|
const void *payload;
|
|
|
|
size_t payload_len;
|
|
|
|
uint64_t ts_ntp;
|
|
|
|
/* The virtual source and destination ports are not used for simple profile */
|
|
|
|
uint16_t virt_src_port;
|
|
|
|
/* These next fields are not needed/used by rist_sender_data_write */
|
|
|
|
uint16_t virt_dst_port;
|
|
|
|
struct rist_peer *peer;
|
|
|
|
uint32_t flow_id;
|
|
|
|
/* Get's populated by librist with the rtp_seq on output, can be used on input to tell librist which rtp_seq to use */
|
|
|
|
uint64_t seq;
|
|
|
|
uint32_t flags;
|
|
|
|
};
|
|
|
|
```
|
|
|
|
out-of-band message blocks:
|
|
|
|
|
|
|
|
```
|
|
|
|
struct rist_oob_block
|
|
|
|
{
|
|
|
|
struct rist_peer *peer;
|
|
|
|
const void *payload;
|
|
|
|
size_t payload_len;
|
|
|
|
uint64_t ts_ntp;
|
|
|
|
};
|
|
|
|
```
|
|
|
|
|
|
|
|
You can easily trace the peer_config struct to the various global and URL options in the ristsender and ristreceiver help pages.
|
|
|
|
|
|
|
|
```
|
|
|
|
struct rist_peer_config
|
|
|
|
{
|
|
|
|
int version;
|
|
|
|
|
|
|
|
/* Communication parameters */
|
|
|
|
// If a value of 0 is specified for address family, the library
|
|
|
|
// will parse the address and populate all communication parameters.
|
|
|
|
// Alternatively, use either AF_INET or AF_INET6 and address will be
|
|
|
|
// treated like an IP address or hostname
|
|
|
|
int address_family;
|
|
|
|
int initiate_conn;
|
|
|
|
char address[RIST_MAX_STRING_LONG];
|
|
|
|
char miface[RIST_MAX_STRING_SHORT];
|
|
|
|
uint16_t physical_port;
|
|
|
|
|
|
|
|
/* Recovery options */
|
|
|
|
enum rist_recovery_mode recovery_mode;
|
|
|
|
uint32_t recovery_maxbitrate;
|
|
|
|
uint32_t recovery_maxbitrate_return;
|
|
|
|
uint32_t recovery_length_min;
|
|
|
|
uint32_t recovery_length_max;
|
|
|
|
uint32_t recovery_reorder_buffer;
|
|
|
|
uint32_t recovery_rtt_min;
|
|
|
|
uint32_t recovery_rtt_max;
|
|
|
|
|
|
|
|
/* Encryption */
|
|
|
|
char secret[RIST_MAX_STRING_SHORT];
|
|
|
|
int key_size;
|
|
|
|
uint32_t key_rotation;
|
|
|
|
|
|
|
|
/* cname identifier for rtcp packets */
|
|
|
|
char cname[RIST_MAX_STRING_SHORT];
|
|
|
|
|
|
|
|
/* Congestion control */
|
|
|
|
enum rist_congestion_control_mode congestion_control_mode;
|
|
|
|
uint32_t min_retries;
|
|
|
|
uint32_t max_retries;
|
|
|
|
|
|
|
|
/* Connection options */
|
|
|
|
uint32_t session_timeout;
|
|
|
|
uint32_t keepalive_interval;
|
|
|
|
};
|
|
|
|
```
|
|
|
|
Various statistics structures
|
|
|
|
|
|
|
|
```
|
|
|
|
struct rist_stats_sender_peer
|
|
|
|
{
|
|
|
|
/* cname */
|
|
|
|
char cname[RIST_MAX_STRING_SHORT];
|
|
|
|
/* internal peer id */
|
|
|
|
uint32_t peer_id;
|
|
|
|
/* avg bandwidth calculation */
|
|
|
|
size_t bandwidth;
|
|
|
|
/* bandwidth devoted to retries */
|
|
|
|
size_t retry_bandwidth;
|
|
|
|
/* num sent packets */
|
|
|
|
uint64_t sent;
|
|
|
|
/* num received packets */
|
|
|
|
uint64_t received;
|
|
|
|
/* retransmitted packets */
|
|
|
|
uint64_t retransmitted;
|
|
|
|
/* quality: Q = (sent * 100.0) / sent + bloat_skipped + retransmit_skipped + retransmitted */
|
|
|
|
double quality;
|
|
|
|
/* current RTT */
|
|
|
|
uint32_t rtt;
|
|
|
|
};
|
|
|
|
struct rist_stats_receiver_flow
|
|
|
|
{
|
|
|
|
/* peer count */
|
|
|
|
uint32_t peer_count;
|
|
|
|
/* combined peer cnames */
|
|
|
|
char cname[RIST_MAX_STRING_LONG];
|
|
|
|
/* flow id (set by senders) */
|
|
|
|
uint32_t flow_id;
|
|
|
|
/* flow status */
|
|
|
|
int status;
|
|
|
|
/* avg bandwidth calculation */
|
|
|
|
size_t bandwidth;
|
|
|
|
/* bandwidth devoted to retries */
|
|
|
|
size_t retry_bandwidth;
|
|
|
|
/* num sent packets */
|
|
|
|
uint64_t sent;
|
|
|
|
/* num received packets */
|
|
|
|
uint64_t received;
|
|
|
|
/* missing, including reordered */
|
|
|
|
uint32_t missing;
|
|
|
|
/* reordered */
|
|
|
|
uint32_t reordered;
|
|
|
|
/* total recovered */
|
|
|
|
uint32_t recovered;
|
|
|
|
/* recovered on the first retry */
|
|
|
|
uint32_t recovered_one_retry;
|
|
|
|
/* lost packets */
|
|
|
|
uint32_t lost;
|
|
|
|
/* quality: Q = (sent * 100.0) / sent + bloat_skipped + retransmit_skipped + retransmitted */
|
|
|
|
double quality;
|
|
|
|
/* packet inter-arrival time (microseconds) */
|
|
|
|
uint64_t min_inter_packet_spacing;
|
|
|
|
uint64_t cur_inter_packet_spacing;
|
|
|
|
uint64_t max_inter_packet_spacing;
|
|
|
|
/* avg rtt all non dead peers */
|
|
|
|
uint32_t rtt;
|
|
|
|
};
|
|
|
|
struct rist_stats
|
|
|
|
{
|
|
|
|
uint32_t json_size;
|
|
|
|
char *stats_json;
|
|
|
|
uint16_t version;
|
|
|
|
enum rist_stats_type stats_type;
|
|
|
|
union {
|
|
|
|
struct rist_stats_sender_peer sender_peer;
|
|
|
|
struct rist_stats_receiver_flow receiver_flow;
|
|
|
|
} stats;
|
|
|
|
};
|
|
|
|
```
|
|
|
|
|
|
|
|
**Private to the Library**
|
|
|
|
|
|
|
|
See src/rist-private.h for a number of definitions used only within the libRIST library. You'll note, for example, that the RIST context is defined there. You'll find another definition in headers.h, but there it's only a pointer to the private definition. If you wish to dive deep into the library to modify it, rather than just "use" it, thoroughly understanding the private headers will be of importance. Here we document only a few key definitions, and highlight only a few key points in hopes of providing just a "20,000 foot view."
|
|
|
|
|
|
|
|
* The context structure consists of the data that identifies the sender, receiver and the connection mode.
|
|
|
|
* The division of labor between library and applications that access it might be described in this way. The library manages the "flow," i.e., sending and receiving the payloads, plus calculating the stats. The application side of it as authorizing/connecting the various senders and receivers and outputting the statistics.
|
|
|
|
* The sender side of the private functions also does the "heavy lifting" as far as load balancing/split paths and redundancy are concerned.
|
|
|
|
* The greater part of the prime tasks of the "private piece" are directly concerned with reading or writing the packet headers defined in the RIST standard and acting accordingly. This ties back to the statement we mad about "modifying" as opposed to "using" the library.
|
|
|
|
* The functions described in the top part of this document are about using the library as opposed to modifying it; they're API functions. But the former task can be made stronger by understanding the latter.
|
|
|
|
* The rist_peer structures are related to this "division of labor." If you intend to create applications with complicated "traffic cop" options, such as described in other parts of the help documents where we discussed sending multiple streams through one RIST connector, but in which the multiple receivers are interensted in some but not all the streams within that connector, thismay helpt.
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
struct rist_ctx {
|
|
|
|
enum rist_ctx_mode mode;
|
|
|
|
struct rist_sender *sender_ctx;
|
|
|
|
struct rist_receiver *receiver_ctx;
|
|
|
|
;
|
|
|
|
struct rist_peer_sender_stats {
|
|
|
|
uint64_t sent;
|
|
|
|
uint32_t received;
|
|
|
|
uint32_t retrans;
|
|
|
|
uint32_t bloat_skip;
|
|
|
|
uint32_t retrans_skip;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct rist_peer_receiver_stats {
|
|
|
|
uint32_t sent;
|
|
|
|
uint64_t recv;
|
|
|
|
uint32_t missing;
|
|
|
|
uint32_t retries;
|
|
|
|
uint32_t recovered;
|
|
|
|
uint32_t reordered;
|
|
|
|
uint32_t dups;
|
|
|
|
uint32_t recovered_0nack;
|
|
|
|
uint32_t recovered_1nack;
|
|
|
|
uint32_t recovered_2nack;
|
|
|
|
uint32_t recovered_3nack;
|
|
|
|
uint32_t recovered_morenack;
|
|
|
|
uint32_t recovered_sum;
|
|
|
|
uint32_t recovered_average;
|
|
|
|
int32_t recovered_slope;
|
|
|
|
uint32_t recovered_slope_inverted;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct rist_flow {
|
|
|
|
volatile int shutdown;
|
|
|
|
int max_output_jitter;
|
|
|
|
|
|
|
|
|
|
|
|
struct rist_buffer *receiver_queue[RIST_SERVER_QUEUE_BUFFERS]; /* output queue */
|
|
|
|
|
|
|
|
|
|
|
|
pthread_rwlock_t queue_lock;
|
|
|
|
|
|
|
|
|
|
|
|
bool receiver_queue_has_items;
|
|
|
|
atomic_ulong receiver_queue_size; /* size in bytes */
|
|
|
|
uint64_t recovery_buffer_ticks; /* size in ticks */
|
|
|
|
uint64_t stats_report_time;
|
|
|
|
/* in ticks */
|
|
|
|
atomic_ulong receiver_queue_output_idx; /* next packet to output */
|
|
|
|
size_t receiver_queue_max;
|
|
|
|
|
|
|
|
|
|
|
|
/* Missing incoming packets, waiting for retransmission */
|
|
|
|
struct rist_missing_buffer *missing;
|
|
|
|
struct rist_missing_buffer *missing_tail;
|
|
|
|
uint32_t missing_counter;
|
|
|
|
|
|
|
|
|
|
|
|
struct rist_peer_flow_stats stats_instant;
|
|
|
|
struct rist_peer_flow_stats stats_total;
|
|
|
|
uint64_t stats_next_time;
|
|
|
|
uint64_t checks_next_time;
|
|
|
|
|
|
|
|
|
|
|
|
/* Missing queue max size */
|
|
|
|
uint32_t missing_counter_max;
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t flow_id;
|
|
|
|
int dead;
|
|
|
|
struct rist_flow *next;
|
|
|
|
struct rist_peer **peer_lst;
|
|
|
|
size_t peer_lst_len;
|
|
|
|
uint32_t last_seq_output;
|
|
|
|
uint64_t last_seq_output_source_time;
|
|
|
|
uint32_t last_seq_found;
|
|
|
|
intptr_t receiver_id;
|
|
|
|
intptr_t sender_id;
|
|
|
|
uint64_t last_ipstats_time;
|
|
|
|
uint64_t last_output_time;
|
|
|
|
uint64_t max_source_time;
|
|
|
|
|
|
|
|
|
|
|
|
int64_t time_offset;//Current offset between our clock and RTP packets.
|
|
|
|
int64_t time_offset_old;//Old offset between our clock and RTP packets.
|
|
|
|
uint64_t time_offset_changed_ts;//Timestamp the RTP counter last wrapped
|
|
|
|
uint64_t last_packet_ts;//Last packet time
|
|
|
|
|
|
|
|
|
|
|
|
bool authenticated;
|
|
|
|
|
|
|
|
|
|
|
|
/* Receiver thread variables */
|
|
|
|
pthread_t receiver_thread;
|
|
|
|
/* data out thread signaling */
|
|
|
|
pthread_cond_t condition;
|
|
|
|
pthread_mutex_t mutex;
|
|
|
|
|
|
|
|
|
|
|
|
/* variable used for seq number length (16bit or 32bit) */
|
|
|
|
bool short_seq;
|
|
|
|
|
|
|
|
|
|
|
|
/* Session timeouts variables */
|
|
|
|
uint64_t session_timeout;
|
|
|
|
uint64_t last_recv_ts;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct rist_receiver {
|
|
|
|
/* data out thread signaling for fifo */
|
|
|
|
pthread_cond_t condition;
|
|
|
|
pthread_mutex_t mutex;
|
|
|
|
|
|
|
|
|
|
|
|
/* Receiver data callback */
|
|
|
|
int (*receiver_data_callback)(void *arg, const struct rist_data_block *data_block);
|
|
|
|
void *receiver_data_callback_argument;
|
|
|
|
|
|
|
|
|
|
|
|
/* Receiver timed async data output */
|
|
|
|
struct rist_data_block *dataout_fifo_queue[RIST_DATAOUT_QUEUE_BUFFERS];
|
|
|
|
size_t dataout_fifo_queue_bytesize;
|
|
|
|
atomic_ulong dataout_fifo_queue_counter;
|
|
|
|
atomic_ulong dataout_fifo_queue_read_index;
|
|
|
|
atomic_ulong dataout_fifo_queue_write_index;
|
|
|
|
|
|
|
|
|
|
|
|
/* Receiver thread variables */
|
|
|
|
pthread_t receiver_thread;
|
|
|
|
|
|
|
|
|
|
|
|
/* Reporting id */
|
|
|
|
intptr_t id;
|
|
|
|
|
|
|
|
|
|
|
|
/* Common stuff */
|
|
|
|
struct rist_common_ctx common;
|
|
|
|
|
|
|
|
|
|
|
|
enum rist_nack_type nack_type;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct rist_sender {
|
|
|
|
/* Advertised flow for this context */
|
|
|
|
uint32_t adv_flow_id;
|
|
|
|
|
|
|
|
|
|
|
|
/* max bitrate of all sender peers (sets the buffer size on sender queue) */
|
|
|
|
uint32_t recovery_maxbitrate_max;
|
|
|
|
uint32_t max_nacksperloop;
|
|
|
|
|
|
|
|
|
|
|
|
/* Sender thread variables */
|
|
|
|
pthread_t sender_thread;
|
|
|
|
/* data/nacks out thread signaling */
|
|
|
|
pthread_cond_t condition;
|
|
|
|
pthread_mutex_t mutex;
|
|
|
|
|
|
|
|
|
|
|
|
bool sender_initialized;
|
|
|
|
uint32_t total_weight;
|
|
|
|
struct rist_buffer *sender_queue[RIST_SERVER_QUEUE_BUFFERS]; /* input queue */
|
|
|
|
size_t sender_queue_bytesize;
|
|
|
|
size_t sender_queue_delete_index;
|
|
|
|
atomic_ulong sender_queue_read_index;
|
|
|
|
atomic_ulong sender_queue_write_index;
|
|
|
|
size_t sender_queue_max;
|
|
|
|
int weight_counter;
|
|
|
|
uint64_t last_datagram_time;
|
|
|
|
bool simulate_loss;
|
|
|
|
uint64_t stats_next_time;
|
|
|
|
uint64_t checks_next_time;
|
|
|
|
uint32_t session_timeout;
|
|
|
|
|
|
|
|
|
|
|
|
/* retry queue */
|
|
|
|
struct rist_retry *sender_retry_queue;
|
|
|
|
size_t sender_retry_queue_write_index;
|
|
|
|
size_t sender_retry_queue_read_index;
|
|
|
|
size_t sender_retry_queue_size;
|
|
|
|
uint64_t cooldown_time;
|
|
|
|
int cooldown_mode;
|
|
|
|
|
|
|
|
|
|
|
|
/* Recovery */
|
|
|
|
uint32_t seq_index[UINT16_SIZE];
|
|
|
|
size_t sender_recover_min_time;
|
|
|
|
|
|
|
|
|
|
|
|
/* Reporting id */
|
|
|
|
intptr_t id;
|
|
|
|
|
|
|
|
|
|
|
|
/* flow_id time-related */
|
|
|
|
struct timeval time;
|
|
|
|
|
|
|
|
|
|
|
|
/* Common stuff */
|
|
|
|
struct rist_common_ctx common;
|
|
|
|
|
|
|
|
|
|
|
|
/* Peer tracking */
|
|
|
|
struct rist_peer **peer_lst;
|
|
|
|
size_t peer_lst_len;
|
|
|
|
|
|
|
|
|
|
|
|
/* Queue lock for fifo buffer */
|
|
|
|
pthread_mutex_t queue_lock;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct rist_peer {
|
|
|
|
/* linked list */
|
|
|
|
struct rist_peer *next;
|
|
|
|
struct rist_peer *prev;
|
|
|
|
|
|
|
|
|
|
|
|
/* For simple profile authentication chain (data and rtcp on different ports) */
|
|
|
|
struct rist_peer *peer_rtcp;
|
|
|
|
struct rist_peer *peer_data;
|
|
|
|
bool is_rtcp;
|
|
|
|
bool is_data;
|
|
|
|
/* sender only: peer is known to respond to echo requests use those to calculate RTT instead */
|
|
|
|
bool echo_enabled;
|
|
|
|
|
|
|
|
|
|
|
|
/* For keeping track of the connection that initiated a peer */
|
|
|
|
struct rist_peer *parent;
|
|
|
|
struct rist_peer *sibling_prev;
|
|
|
|
struct rist_peer *sibling_next;
|
|
|
|
struct rist_peer *child;
|
|
|
|
uint32_t child_alive_count;
|
|
|
|
|
|
|
|
|
|
|
|
/* Flow for incoming traffic */
|
|
|
|
struct rist_flow *flow;
|
|
|
|
|
|
|
|
|
|
|
|
/* Advertised flow id to force peer selection */
|
|
|
|
uint32_t adv_flow_id;
|
|
|
|
|
|
|
|
|
|
|
|
/* Identifiers for multipeer links */
|
|
|
|
uint32_t adv_peer_id;
|
|
|
|
|
|
|
|
|
|
|
|
char receiver_name[RIST_MAX_HOSTNAME];
|
|
|
|
|
|
|
|
|
|
|
|
/* Config */
|
|
|
|
struct rist_peer_config config;
|
|
|
|
uint64_t recovery_buffer_ticks;
|
|
|
|
|
|
|
|
|
|
|
|
bool buffer_bloat_active;
|
|
|
|
|
|
|
|
|
|
|
|
bool receiver_mode;
|
|
|
|
|
|
|
|
|
|
|
|
int sd;
|
|
|
|
|
|
|
|
|
|
|
|
/* States */
|
|
|
|
enum rist_peer_state state_local;
|
|
|
|
enum rist_peer_state state_peer;
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t retries;
|
|
|
|
|
|
|
|
|
|
|
|
/* Data sending */
|
|
|
|
uint32_t seq;
|
|
|
|
uint32_t eight_times_rtt;
|
|
|
|
uint32_t w_count; /* Counter for weight in distributed send */
|
|
|
|
|
|
|
|
|
|
|
|
/* RTT statistics */
|
|
|
|
uint32_t last_mrtt;
|
|
|
|
|
|
|
|
|
|
|
|
/* Missing queue max size */
|
|
|
|
uint32_t missing_counter_max;
|
|
|
|
|
|
|
|
|
|
|
|
/* Encryption */
|
|
|
|
struct rist_key key_secret; // used for received packets
|
|
|
|
#ifdef __linux
|
|
|
|
struct linux_crypto *cryptoctx;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/* compression flag (sender only) */
|
|
|
|
bool compression;
|
|
|
|
|
|
|
|
|
|
|
|
/* Addressing */
|
|
|
|
uint16_t local_port;
|
|
|
|
uint16_t remote_port;
|
|
|
|
union {
|
|
|
|
struct sockaddr address;
|
|
|
|
struct sockaddr_in inaddr;
|
|
|
|
struct sockaddr_in6 inaddr6;
|
|
|
|
struct sockaddr_storage storage;
|
|
|
|
} u;
|
|
|
|
socklen_t address_len;
|
|
|
|
uint16_t address_family;
|
|
|
|
uint16_t state;
|
|
|
|
char miface[128];
|
|
|
|
|
|
|
|
|
|
|
|
/* Events */
|
|
|
|
struct timeval expire;
|
|
|
|
bool send_keepalive;
|
|
|
|
struct evsocket_event *event_recv;
|
|
|
|
|
|
|
|
|
|
|
|
/* listening mode with @ */
|
|
|
|
bool listening;
|
|
|
|
|
|
|
|
|
|
|
|
/* rist ctx */
|
|
|
|
struct rist_sender *sender_ctx;
|
|
|
|
struct rist_receiver *receiver_ctx;
|
|
|
|
|
|
|
|
|
|
|
|
/* rist buffer bloating counteract */
|
|
|
|
uint64_t cooldown_time;
|
|
|
|
|
|
|
|
|
|
|
|
/* Statistics Sender */
|
|
|
|
struct rist_peer_sender_stats stats_sender_instant;
|
|
|
|
struct rist_peer_sender_stats stats_sender_total;
|
|
|
|
|
|
|
|
|
|
|
|
/* Statistics Receiver */
|
|
|
|
struct rist_peer_receiver_stats stats_receiver_instant;
|
|
|
|
struct rist_peer_receiver_stats stats_receiver_total;
|
|
|
|
|
|
|
|
|
|
|
|
int dead;
|
|
|
|
uint64_t birthtime_peer;
|
|
|
|
uint64_t birthtime_local;
|
|
|
|
|
|
|
|
|
|
|
|
/* bw estimation */
|
|
|
|
struct rist_bandwidth_estimation bw;
|
|
|
|
struct rist_bandwidth_estimation retry_bw;
|
|
|
|
|
|
|
|
|
|
|
|
/* Temporary buffer for grouping and sending nacks */
|
|
|
|
struct nacks nacks;
|
|
|
|
|
|
|
|
|
|
|
|
/* shutting down flag */
|
|
|
|
volatile bool shutdown;
|
|
|
|
|
|
|
|
|
|
|
|
/* Timers */
|
|
|
|
uint32_t rtcp_keepalive_interval;
|
|
|
|
uint64_t keepalive_next_time;
|
|
|
|
uint32_t session_timeout;
|
|
|
|
uint64_t last_rtcp_received;
|
|
|
|
uint64_t last_sender_report_time;
|
|
|
|
uint64_t last_sender_report_ts;
|
|
|
|
|
|
|
|
|
|
|
|
char *url;
|
|
|
|
char cname[RIST_MAX_HOSTNAME];
|
|
|
|
};
|
|
|
|
``` |
|
|
|
\ No newline at end of file |