summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/config.h46
-rw-r--r--include/ice.h129
-rw-r--r--include/peerconn.h140
-rw-r--r--include/runloop.h111
-rw-r--r--include/str.h34
-rw-r--r--include/stun.h134
-rw-r--r--include/urtc.h34
-rw-r--r--include/urtc/opts.h22
8 files changed, 650 insertions, 0 deletions
diff --git a/include/config.h b/include/config.h
new file mode 100644
index 0000000..a003218
--- /dev/null
+++ b/include/config.h
@@ -0,0 +1,46 @@
+/*
+ * liburtc
+ * Copyright (C) 2019 Chris Hiszpanski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef URTC_CONFIG_H
+#define URTC_CONFIG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "ice.h"
+
+/* Peer connection configuration */
+typedef struct urtc_config {
+ urtc_ice_server_t ice_servers[ICE_MAX_SERVERS];
+
+ // TODO video_source_t *vsrc;
+ // TODO video_sink_t *vsnk;
+
+ // TODO audio_source_t *asrc;
+ // TODO audio_sink_t *asnk;
+
+ // TODO data_source_t *dsrc;
+ // TODO data_sink_t *dsnk;
+} urtc_config_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* URTC_CONFIG_H */
diff --git a/include/ice.h b/include/ice.h
new file mode 100644
index 0000000..8b7251f
--- /dev/null
+++ b/include/ice.h
@@ -0,0 +1,129 @@
+/*
+ * liburtc
+ * Copyright (C) 2019 Chris Hiszpanski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef URTC_ICE_H
+#define URTC_ICE_H
+
+#include <pthread.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <sys/select.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Maximum number of ICE bases. Each network interface address is a base. */
+#define ICE_MAX_BASES 16
+
+/* Maximum number of supported ICE (i.e. STUN or TURN) servers */
+#define ICE_MAX_SERVERS 16
+
+
+///////////////////////////// TYPE DEFINITIONS /////////////////////////////
+
+// STUN or TURN server
+typedef struct {
+ char *url;
+ char *username; /* ignored for stun urls */
+ char *credential; /* ignored for stun urls */
+} urtc_ice_server_t;
+
+// ICE base
+typedef struct {
+} ice_base_t;
+
+// ICE component
+typedef enum {
+ ICE_COMPONENT_NULL = 0,
+ ICE_COMPONENT_RTP,
+ ICE_COMPONENT_RTCP
+} ice_component_t;
+
+// ICE candidate
+typedef struct {
+ ice_component_t component;
+ uint16_t port;
+ uint32_t priority;
+} ice_candidate_t;
+
+typedef struct {
+ ice_candidate_t local;
+ ice_candidate_t remote;
+} ice_candidate_pair_t;
+
+// See https://tools.ietf.org/html/rfc8445#section-6.1.2.1
+typedef enum {
+ CHECKLIST_STATE_RUNNING = 0,
+ CHECKLIST_STATE_COMPLETED,
+ CHECKLIST_STATE_FAILED
+} ice_checklist_state_t;
+
+typedef struct {
+ ice_checklist_state_t state;
+} ice_checklist_t;
+
+// ICE agent object
+typedef struct {
+ pthread_t thread;
+ ice_checklist_t checklist;
+ ice_base_t bases[ICE_MAX_BASES];
+
+ int nfds;
+ fd_set readfds;
+ fd_set writefds;
+ fd_set errorfds;
+
+ struct timeval ta;
+
+ bool cancelled;
+} ice_agent_t;
+
+
+/////////////////////////// FORWARD DECLARATIONS ///////////////////////////
+
+/**
+ * Create new ICE agent
+ *
+ * Each agent creates a separate thread for processing network i/o events.
+ *
+ * \param agent[out] Pointer to agent object pointer
+ *
+ * \return 0 on success. Negative on error.
+ */
+int ice_agent_create(ice_agent_t **agent);
+
+/**
+ * Destroy ICE agent
+ *
+ * Stops agent thread (if running) and frees memory.
+ *
+ * \param agent[in] Pointer to agent object
+ *
+ * \return 0 on success. Negative on error.
+ */
+int ice_agent_destroy(ice_agent_t *agent);
+
+int ice_gather_host_candidates();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* URTC_ICE_H */
diff --git a/include/peerconn.h b/include/peerconn.h
new file mode 100644
index 0000000..feecc0e
--- /dev/null
+++ b/include/peerconn.h
@@ -0,0 +1,140 @@
+/*
+ * liburtc
+ * Copyright (C) 2019 Chris Hiszpanski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef URTC_PEERCONN_H
+#define URTC_PEERCONN_H
+
+#include "config.h"
+#include "ice.h"
+#include "sdp.h"
+#include "runloop.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**************************** TYPE DEFINITIONS ****************************/
+
+// Event callback function type. Takes and returns void pointers.
+typedef void *(*event_callback_t)(void *arg);
+
+// Peer connection
+typedef struct urtc_peerconn {
+ uint8_t n;
+
+ // Interactive connectivity establishment agent
+ ice_agent_t *agent;
+
+ // Local and remote session descriptions
+ urtc_sdp_t *ldesc;
+ urtc_sdp_t *rdesc;
+
+ // Event callbacks
+ void (*onIceCandidate)(const char *cand, void *arg);
+ void (*onIceGatheringStateChange)(int state);
+ void (*onIceConnectionStateChange)(int state);
+ void (*onSignalingStateChange)(int state);
+ void (*onTrack)(int track);
+
+ // Run loop for event handling
+ runloop_t runloop;
+} urtc_peerconn_t;
+
+
+/************************** FORWARD DECLARATIONS **************************/
+
+/**
+ * Create a new peer connection.
+ *
+ * \param pc[out] New peer connection.
+ * \param cfg[in] Peer connection configuration.
+ *
+ * \return 0 on success. Negative on error.
+ */
+int urtc_peerconn_create(urtc_peerconn_t **pc, const urtc_config_t *cfg);
+
+/**
+ * Adds received ICE candidate to ICE agent.
+ *
+ * If `cand` is a NULL pointer or empty string, it signals that all remote
+ * candidates have been delivered (i.e. end-of-candidates).
+ *
+ * \param pc[in] Peer connection.
+ * \param cand[in] ICE candidate.
+ *
+ * \return 0 on success. Negative on error.
+ */
+int urtc_peerconn_add_ice_candidate(urtc_peerconn_t *pc, const char *cand);
+
+/**
+ * Set remote description.
+ *
+ * \param pc[in] Peer connection.
+ * \param desc[in] Session description protocol string.
+ *
+ * \return 0 on success. Negative on error.
+ */
+int urtc_peerconn_set_remote_description(urtc_peerconn_t *pc, const char *desc);
+
+/**
+ * Set local description.
+ *
+ * \param pc[in] Peer connection.
+ * \param desc[in] Session description protocol string.
+ *
+ * \return 0 on success. Negative on error.
+ */
+int urtc_peerconn_set_local_description(urtc_peerconn_t *pc, const char *desc);
+
+/**
+ * Create offer.
+ *
+ * \param pc[in] Peer connection.
+ * \param offer[out] Session description to send to remote peer. Caller must
+ * free.
+ *
+ * \return 0 on success. Negative on error.
+ */
+int urtc_peerconn_create_offer(urtc_peerconn_t *pc, char **offer);
+
+/**
+ * Create answer.
+ *
+ * \param pc[in] Peer connection
+ * \param answer[out] Session description to send to remote peer. Caller must
+ * free.
+ *
+ * \return 0 on success. Negative on error.
+ */
+int urtc_peerconn_create_answer(urtc_peerconn_t *pc, char **answer);
+
+/**
+ * Teardown a peer connection.
+ *
+ * \param pc[in] Peer connection.
+ *
+ * \return 0 on success. Negative on error.
+ */
+int urtc_peerconn_destroy(urtc_peerconn_t *pc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* URTC_PEERCONN_H */
diff --git a/include/runloop.h b/include/runloop.h
new file mode 100644
index 0000000..ea840e7
--- /dev/null
+++ b/include/runloop.h
@@ -0,0 +1,111 @@
+/*
+ * liburtc
+ * Copyright (C) 2019 Chris Hiszpanski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @file runloop.h
+ * Event loop
+ * A more elaborate file description.
+ */
+
+#ifndef URTC_RUNLOOP_H
+#define URTC_RUNLOOP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <poll.h>
+#include <pthread.h>
+#include <stdbool.h>
+
+typedef void *(*callback_t)(int fd, void *arg);
+
+typedef struct {
+ // File descriptor sets for poll().
+ struct pollfd *fds;
+ nfds_t nfds;
+
+ // Callback array. Index into array is file descriptor.
+ callback_t *callbacks;
+ void **args;
+
+ // Pipe for aborting blocked poll(). Allows dynamic adds/removes.
+ int abortpipe[2];
+ bool done;
+
+ // Run loop thread ID
+ pthread_t tid;
+} runloop_t;
+
+/**
+ * Create a new run loop
+ *
+ * Each run loop creates a separate thread which then repeatedly poll()s
+ * for events. Upon receiving an event, the run loop calls the respective
+ * file descriptor's callback function.
+ *
+ * @param[out] rl Pointer to run loop struct
+ */
+int urtc__runloop_create(runloop_t *rl);
+
+/**
+ * Add file descriptor to run loop
+ *
+ * @param rl Run loop
+ * @param fd File descriptor
+ * @param events Events to monitor (see struct pollfd)
+ * @param cb Callback to run on activity
+ * @param arg User-specified argument to pass to callback
+ *
+ * @return Zero on success. Negative on error.
+ */
+int urtc__runloop_add(
+ runloop_t *rl,
+ int fd,
+ short events,
+ void *(*cb)(int fd, void *arg),
+ void *arg
+);
+
+/**
+ * Remove a file descriptor from the run loop. No more events will be
+ * processed for this file descriptor.
+ *
+ * @param rl Run loop.
+ * @param fd File descriptor.
+ *
+ * @return Zero on success. Negative on error.
+ */
+int urtc__runloop_remove(runloop_t *rl, int fd);
+
+int urtc__runloop_join(runloop_t *rl);
+
+/**
+ * Destroy a run loop
+ *
+ * @param rl Pointer to run loop object
+ *
+ * @return Zero on success; negative on error. On error, errno is set.
+ */
+int urtc__runloop_destroy(runloop_t *rl);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* URTC_RUNLOOP_H */
diff --git a/include/str.h b/include/str.h
new file mode 100644
index 0000000..f0164d3
--- /dev/null
+++ b/include/str.h
@@ -0,0 +1,34 @@
+/*
+ * liburtc
+ * Copyright (C) 2019 Chris Hiszpanski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef URTC_STR_H
+#define URTC_STR_H
+
+#include <stddef.h>
+
+typedef struct {
+ char *string;
+ size_t length;
+ size_t capacity;
+} str_t;
+
+str_t str_create_empty(size_t capacity);
+str_t str_append(const str_t str, const char *c_str);
+void str_destroy(str_t s);
+
+#endif
diff --git a/include/stun.h b/include/stun.h
new file mode 100644
index 0000000..126e7f5
--- /dev/null
+++ b/include/stun.h
@@ -0,0 +1,134 @@
+/*
+ * liburtc
+ * Copyright (C) 2019 Chris Hiszpanski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef URTC_STUN_H
+#define URTC_STUN_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SIZEOF_STUN_HDR 20
+
+// STUN Classes
+#define STUN_CLASS_REQUEST 0
+#define STUN_CLASS_INDICTATION 1
+#define STUN_CLASS_SUCCESS 2
+#define STUN_CLASS_ERROR 3
+
+// STUN Methods
+#define STUN_METHOD_RESERVED 0
+#define STUN_METHOD_BINDING 1
+
+
+///////////////////////////// TYPE DEFINITIONS /////////////////////////////
+
+typedef struct {
+ int rc; // Retransmission count
+ int rto; // Retransmission timeout (in ms)
+ int sockfd; // Socket file descriptor
+} stun_client_t;
+
+typedef struct {
+ char *server;
+} stun_client_config_t;
+
+// STUN Message Header
+typedef struct __attribute__((__packed__)) {
+ uint16_t reserved:2; // Upper two bits are 0
+ uint16_t type:14; // 14-bit type
+ uint16_t msglen; // Message length
+ uint32_t cookie; // Magic cookie
+ uint8_t txid[12]; // Transaction ID
+} stun_msg_hdr_t;
+
+// STUN Attribute
+typedef struct {
+ uint16_t type; // Attribute type
+ uint16_t len; // Value length, prior to padding
+ uint8_t *val; // Pointer to attribute value
+} stun_attr_t;
+
+// STUN Attribute: MAPPED-ADDRESS
+typedef struct __attribute__((__packed__)) {
+ uint8_t reserved;
+ uint8_t family;
+ uint16_t port;
+ union {
+ uint8_t ipv4[4]; // IPv4 address is 32-bits
+ uint8_t ipv6[16]; // IPv6 address is 128-bits
+ };
+} stun_attr_mapped_address_t;
+
+// STUN Attribute: XOR-MAPPED-ADDRESS
+typedef stun_attr_mapped_address_t stun_attr_xor_mapped_address_t;
+
+// STUN Attribute: USERNAME
+
+
+////////////////////////////////// MACROS //////////////////////////////////
+
+// Get class from message header type
+#define CLASS(typ) (((typ >> 7) & 0x2) | ((typ >> 4) & 0x1))
+
+// Get method from message header type
+#define METHOD(typ) (((typ >> 2) & 0xF80) | ((typ >> 1) & 0x70) | (typ & 0xF))
+
+#define TYPE(cls, mthd) ( \
+ ((mthd & 0xF80) << 2) | \
+ ((cls & 0x2) << 7) | \
+ ((mthd & 0x70) << 1) | \
+ ((cls & 0x1) << 4) | \
+ (mthd & 0xF) \
+)
+
+
+/////////////////////////// FORWARD DECLARATIONS ///////////////////////////
+
+/**
+ * (callback) Binding request response handler
+ *
+ * @param[in] name
+ * @param[in] arg User argument
+ */
+typedef void (*stun_client_binding_response_callback)(
+ const char *name,
+ void *arg
+);
+
+/**
+ * Sends a STUN binding request to the specified server
+ *
+ * @param[in] srv Server (hostname or IP address)
+ * @param[in] cb Handler to call when a response is received
+ * @param[in] arg Optional user argument to pass to callback
+ */
+err_t stun_client_binding_request(
+ runloop_t *rl,
+ const char *srv,
+ stun_client_binding_response_callback cb,
+ void *arg
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* URTC_STUN_H */
diff --git a/include/urtc.h b/include/urtc.h
new file mode 100644
index 0000000..3eabba0
--- /dev/null
+++ b/include/urtc.h
@@ -0,0 +1,34 @@
+/*
+ * liburtc
+ * Copyright (C) 2019 Chris Hiszpanski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef URTC_H
+#define URTC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "config.h"
+#include "err.h"
+#include "peerconn.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* URTC_H */
diff --git a/include/urtc/opts.h b/include/urtc/opts.h
new file mode 100644
index 0000000..7e5200b
--- /dev/null
+++ b/include/urtc/opts.h
@@ -0,0 +1,22 @@
+/*
+ * liburtc
+ * Copyright (C) 2019 Chris Hiszpanski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef URTC_OPTS_H
+#define URTC_OPTS_H
+
+#endif /* URTC_OPTS_H */