Squashed 'third_party/rawrtc/rawrtc/' content from commit aa3ae4b24
Change-Id: I38a655a4259b62f591334e90a1315bd4e7e4d8ec
git-subtree-dir: third_party/rawrtc/rawrtc
git-subtree-split: aa3ae4b247275cc6e69c30613b3a4ba7fdc82d1b
diff --git a/src/peer_connection_configuration/configuration.c b/src/peer_connection_configuration/configuration.c
new file mode 100644
index 0000000..c1f2b71
--- /dev/null
+++ b/src/peer_connection_configuration/configuration.c
@@ -0,0 +1,260 @@
+#include "configuration.h"
+#include "../certificate/certificate.h"
+#include "../ice_server/server.h"
+#include "../utils/utils.h"
+#include <rawrtc/ice_gather_options.h>
+#include <rawrtc/peer_connection_configuration.h>
+#include <rawrtc/utils.h>
+#include <rawrtcc/code.h>
+#include <rawrtcdc/sctp_transport.h>
+#include <re.h>
+#include <limits.h> // INT_MAX
+
+/*
+ * Destructor for an existing peer connection configuration.
+ */
+static void rawrtc_peer_connection_configuration_destroy(void* arg) {
+ struct rawrtc_peer_connection_configuration* const configuration = arg;
+
+ // Un-reference
+ list_flush(&configuration->certificates);
+ list_flush(&configuration->ice_servers);
+}
+
+/*
+ * Create a new peer connection configuration.
+ * `*configurationp` must be unreferenced.
+ */
+enum rawrtc_code rawrtc_peer_connection_configuration_create(
+ struct rawrtc_peer_connection_configuration** const configurationp, // de-referenced
+ enum rawrtc_ice_gather_policy const gather_policy) {
+ struct rawrtc_peer_connection_configuration* configuration;
+
+ // Check arguments
+ if (!configurationp) {
+ return RAWRTC_CODE_INVALID_ARGUMENT;
+ }
+
+ // Allocate
+ configuration =
+ mem_zalloc(sizeof(*configuration), rawrtc_peer_connection_configuration_destroy);
+ if (!configuration) {
+ return RAWRTC_CODE_NO_MEMORY;
+ }
+
+ // Set fields/reference
+ configuration->gather_policy = gather_policy;
+ list_init(&configuration->ice_servers);
+ list_init(&configuration->certificates);
+ configuration->sctp_sdp_05 = true;
+ configuration->sctp.send_buffer_length = 0;
+ configuration->sctp.receive_buffer_length = 0;
+ configuration->sctp.congestion_ctrl_algorithm = RAWRTC_SCTP_TRANSPORT_CONGESTION_CTRL_RFC2581;
+ configuration->sctp.mtu = 0;
+ configuration->sctp.mtu_discovery = false;
+
+ // Set pointer and return
+ *configurationp = configuration;
+ return RAWRTC_CODE_SUCCESS;
+}
+
+/*
+ * Add an ICE server instance to the peer connection configuration.
+ */
+enum rawrtc_code rawrtc_peer_connection_configuration_add_ice_server_internal(
+ struct rawrtc_peer_connection_configuration* const configuration,
+ struct rawrtc_ice_server* const server) {
+ // Check arguments
+ if (!configuration || !server) {
+ return RAWRTC_CODE_INVALID_ARGUMENT;
+ }
+
+ // Add to configuration
+ list_append(&configuration->ice_servers, &server->le, server);
+ return RAWRTC_CODE_SUCCESS;
+}
+
+/*
+ * Add an ICE server to the peer connection configuration.
+ */
+enum rawrtc_code rawrtc_peer_connection_configuration_add_ice_server(
+ struct rawrtc_peer_connection_configuration* const configuration,
+ char* const* const urls, // copied
+ size_t const n_urls,
+ char* const username, // nullable, copied
+ char* const credential, // nullable, copied
+ enum rawrtc_ice_credential_type const credential_type) {
+ struct rawrtc_ice_server* server;
+ enum rawrtc_code error;
+
+ // Check arguments
+ if (!configuration) {
+ return RAWRTC_CODE_INVALID_ARGUMENT;
+ }
+
+ // Ensure there are less than 2^8 servers
+ // TODO: This check should be in some common location
+ if (list_count(&configuration->ice_servers) == UINT8_MAX) {
+ return RAWRTC_CODE_INSUFFICIENT_SPACE;
+ }
+
+ // Create ICE server
+ error = rawrtc_ice_server_create(&server, urls, n_urls, username, credential, credential_type);
+ if (error) {
+ return error;
+ }
+
+ // Add to configuration
+ return rawrtc_peer_connection_configuration_add_ice_server_internal(configuration, server);
+}
+
+/*
+ * Get ICE servers from the peer connection configuration.
+ * `*serversp` must be unreferenced.
+ */
+enum rawrtc_code rawrtc_peer_connection_configuration_get_ice_servers(
+ struct rawrtc_ice_servers** const serversp, // de-referenced
+ struct rawrtc_peer_connection_configuration* const configuration) {
+ // Check arguments
+ if (!serversp || !configuration) {
+ return RAWRTC_CODE_INVALID_ARGUMENT;
+ }
+
+ // Hand out list as array
+ // Note: ICE servers handed out cannot be added to other lists
+ // without copying since the items are only referenced.
+ return rawrtc_list_to_array(
+ (struct rawrtc_array_container**) serversp, &configuration->ice_servers, true);
+}
+
+/*
+ * Add a certificate to the peer connection configuration to be used
+ * instead of an ephemerally generated one.
+ */
+enum rawrtc_code rawrtc_peer_connection_configuration_add_certificate(
+ struct rawrtc_peer_connection_configuration* configuration,
+ struct rawrtc_certificate* const certificate // copied
+) {
+ enum rawrtc_code error;
+ struct rawrtc_certificate* certificate_copy;
+
+ // Check arguments
+ if (!configuration || !certificate) {
+ return RAWRTC_CODE_INVALID_ARGUMENT;
+ }
+
+ // Copy certificate
+ // Note: Copying is needed as the 'le' element cannot be associated to multiple lists
+ error = rawrtc_certificate_copy(&certificate_copy, certificate);
+ if (error) {
+ return error;
+ }
+
+ // Append to list
+ list_append(&configuration->certificates, &certificate_copy->le, certificate_copy);
+ return RAWRTC_CODE_SUCCESS;
+}
+
+/*
+ * Get certificates from the peer connection configuration.
+ * `*certificatesp` must be unreferenced.
+ */
+enum rawrtc_code rawrtc_peer_connection_configuration_get_certificates(
+ struct rawrtc_certificates** const certificatesp, // de-referenced
+ struct rawrtc_peer_connection_configuration* const configuration) {
+ // Check arguments
+ if (!certificatesp || !configuration) {
+ return RAWRTC_CODE_INVALID_ARGUMENT;
+ }
+
+ // Hand out list as array
+ // Note: Certificates handed out cannot be added to other lists
+ // without copying since the items are only referenced.
+ return rawrtc_list_to_array(
+ (struct rawrtc_array_container**) certificatesp, &configuration->certificates, true);
+}
+
+/*
+ * Set whether to use legacy SDP for data channel parameter encoding.
+ * Note: Legacy SDP for data channels is on by default due to parsing problems in Chrome.
+ */
+enum rawrtc_code rawrtc_peer_connection_configuration_set_sctp_sdp_05(
+ struct rawrtc_peer_connection_configuration* configuration, bool const on) {
+ // Check parameters
+ if (!configuration) {
+ return RAWRTC_CODE_INVALID_ARGUMENT;
+ }
+
+ // Set
+ configuration->sctp_sdp_05 = on;
+ return RAWRTC_CODE_SUCCESS;
+}
+
+/*
+ * Set the SCTP transport's send and receive buffer length in bytes.
+ * If both values are zero, the default buffer length will be used. Otherwise,
+ * zero is invalid.
+ */
+enum rawrtc_code rawrtc_peer_connection_configuration_set_sctp_buffer_length(
+ struct rawrtc_peer_connection_configuration* configuration,
+ uint32_t const send_buffer_length,
+ uint32_t const receive_buffer_length) {
+ // Check arguments
+ if (!configuration || send_buffer_length > INT_MAX || receive_buffer_length > INT_MAX ||
+ (send_buffer_length == 0 && receive_buffer_length != 0) ||
+ (send_buffer_length != 0 && receive_buffer_length == 0)) {
+ return RAWRTC_CODE_INVALID_ARGUMENT;
+ }
+
+ // Set length for send/receive buffer
+ configuration->sctp.send_buffer_length = send_buffer_length;
+ configuration->sctp.receive_buffer_length = receive_buffer_length;
+ return RAWRTC_CODE_SUCCESS;
+}
+
+/*
+ * Set the SCTP transport's congestion control algorithm.
+ */
+enum rawrtc_code rawrtc_peer_connection_configuration_set_sctp_congestion_ctrl_algorithm(
+ struct rawrtc_peer_connection_configuration* configuration,
+ enum rawrtc_sctp_transport_congestion_ctrl const algorithm) {
+ // Check arguments
+ if (!configuration) {
+ return RAWRTC_CODE_INVALID_ARGUMENT;
+ }
+
+ // Set
+ configuration->sctp.congestion_ctrl_algorithm = algorithm;
+ return RAWRTC_CODE_SUCCESS;
+}
+
+/*
+ * Set the SCTP transport's maximum transmission unit (MTU).
+ * A value of zero indicates that the default MTU should be used.
+ */
+enum rawrtc_code rawrtc_peer_connection_configuration_set_sctp_mtu(
+ struct rawrtc_peer_connection_configuration* configuration, uint32_t const mtu) {
+ // Check arguments
+ if (!configuration) {
+ return RAWRTC_CODE_INVALID_ARGUMENT;
+ }
+
+ // Set
+ configuration->sctp.mtu = mtu;
+ return RAWRTC_CODE_SUCCESS;
+}
+
+/*
+ * Enable or disable MTU discovery on the SCTP transport.
+ */
+enum rawrtc_code rawrtc_peer_connection_configuration_set_sctp_mtu_discovery(
+ struct rawrtc_peer_connection_configuration* configuration, bool const on) {
+ // Check arguments
+ if (!configuration) {
+ return RAWRTC_CODE_INVALID_ARGUMENT;
+ }
+
+ // Set
+ configuration->sctp.mtu_discovery = on;
+ return RAWRTC_CODE_SUCCESS;
+}