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/ice_candidate/helper.c b/src/ice_candidate/helper.c
new file mode 100644
index 0000000..ff74c71
--- /dev/null
+++ b/src/ice_candidate/helper.c
@@ -0,0 +1,209 @@
+#include "helper.h"
+#include "../ice_gatherer/gatherer.h"
+#include "../ice_server/server.h"
+#include <rawrtc/main.h>
+#include <rawrtcc/code.h>
+#include <rawrtcc/utils.h>
+#include <re.h>
+#include <rew.h>
+
+/*
+ * Destructor for an existing candidate helper.
+ */
+static void rawrtc_candidate_helper_destroy(void* arg) {
+ struct rawrtc_candidate_helper* const local_candidate = arg;
+
+ // Un-reference
+ list_flush(&local_candidate->stun_sessions);
+ mem_deref(local_candidate->udp_helper);
+ mem_deref(local_candidate->candidate);
+ mem_deref(local_candidate->gatherer);
+}
+
+/*
+ * Create a candidate helper.
+ */
+enum rawrtc_code rawrtc_candidate_helper_create(
+ struct rawrtc_candidate_helper** const candidate_helperp, // de-referenced
+ struct rawrtc_ice_gatherer* gatherer,
+ struct ice_lcand* const candidate,
+ udp_helper_recv_h* const receive_handler,
+ void* const arg) {
+ struct rawrtc_candidate_helper* candidate_helper;
+ enum rawrtc_code error;
+
+ // Check arguments
+ if (!candidate_helperp || !gatherer || !candidate || !receive_handler) {
+ return RAWRTC_CODE_INVALID_ARGUMENT;
+ }
+
+ // Create candidate helper
+ candidate_helper = mem_zalloc(sizeof(*candidate_helper), rawrtc_candidate_helper_destroy);
+ if (!candidate_helper) {
+ return RAWRTC_CODE_NO_MEMORY;
+ }
+
+ // Set fields
+ candidate_helper->gatherer = mem_ref(gatherer);
+ candidate_helper->candidate = mem_ref(candidate);
+ candidate_helper->srflx_pending_count = 0;
+ candidate_helper->relay_pending_count = 0;
+
+ // Set receive handler
+ error = rawrtc_candidate_helper_set_receive_handler(candidate_helper, receive_handler, arg);
+ if (error) {
+ goto out;
+ }
+
+out:
+ if (error) {
+ mem_deref(candidate_helper);
+ } else {
+ // Set pointer
+ *candidate_helperp = candidate_helper;
+ }
+ return error;
+}
+
+/*
+ * Set a candidate helper's receive handler.
+ */
+enum rawrtc_code rawrtc_candidate_helper_set_receive_handler(
+ struct rawrtc_candidate_helper* const candidate_helper,
+ udp_helper_recv_h* const receive_handler,
+ void* const arg) {
+ enum rawrtc_code error;
+ struct udp_helper* udp_helper;
+ struct udp_sock* udp_socket;
+
+ // Check arguments
+ if (!candidate_helper || !receive_handler) {
+ return RAWRTC_CODE_INVALID_ARGUMENT;
+ }
+
+ // Get local candidate's UDP socket
+ udp_socket = trice_lcand_sock(candidate_helper->gatherer->ice, candidate_helper->candidate);
+ if (!udp_socket) {
+ return RAWRTC_CODE_NO_SOCKET;
+ }
+
+ // Create UDP helper
+ error = rawrtc_error_to_code(udp_register_helper(
+ &udp_helper, udp_socket, RAWRTC_LAYER_DTLS_SRTP_STUN, NULL, receive_handler, arg));
+ if (error) {
+ return error;
+ }
+
+ // Unset current helper (if any) and set new helper
+ mem_deref(candidate_helper->udp_helper);
+ candidate_helper->udp_helper = udp_helper;
+
+ // TODO: What about TCP helpers?
+
+ // Done
+ return RAWRTC_CODE_SUCCESS;
+}
+
+/*
+ * Find a specific candidate helper by re candidate.
+ */
+enum rawrtc_code rawrtc_candidate_helper_find(
+ struct rawrtc_candidate_helper** const candidate_helperp,
+ struct list* const candidate_helpers,
+ struct ice_lcand* re_candidate) {
+ struct le* le;
+
+ // Check arguments
+ if (!candidate_helperp || !candidate_helpers || !re_candidate) {
+ return RAWRTC_CODE_INVALID_ARGUMENT;
+ }
+
+ // Lookup candidate helper
+ for (le = list_head(candidate_helpers); le != NULL; le = le->next) {
+ struct rawrtc_candidate_helper* const candidate_helper = le->data;
+ if (candidate_helper->candidate->us == re_candidate->us) {
+ // Found
+ *candidate_helperp = candidate_helper;
+ return RAWRTC_CODE_SUCCESS;
+ }
+ }
+
+ // Not found
+ return RAWRTC_CODE_NO_VALUE;
+}
+
+static void rawrtc_candidate_helper_stun_session_destroy(void* arg) {
+ struct rawrtc_candidate_helper_stun_session* const session = arg;
+
+ // Remove from list
+ list_unlink(&session->le);
+
+ // Un-reference
+ mem_deref(session->url);
+ mem_deref(session->stun_keepalive);
+ mem_deref(session->candidate_helper);
+}
+
+/*
+ * Create a STUN session.
+ */
+enum rawrtc_code rawrtc_candidate_helper_stun_session_create(
+ struct rawrtc_candidate_helper_stun_session** const sessionp, // de-referenced
+ struct rawrtc_ice_server_url* const url) {
+ struct rawrtc_candidate_helper_stun_session* session;
+
+ // Check arguments
+ if (!sessionp || !url) {
+ return RAWRTC_CODE_INVALID_ARGUMENT;
+ }
+
+ // Allocate
+ session = mem_zalloc(sizeof(*session), rawrtc_candidate_helper_stun_session_destroy);
+ if (!session) {
+ return RAWRTC_CODE_NO_MEMORY;
+ }
+
+ // Set fields/reference
+ session->url = mem_ref(url);
+ session->pending = true;
+
+ // Set pointer & done
+ *sessionp = session;
+ return RAWRTC_CODE_SUCCESS;
+}
+
+/*
+ * Add a STUN session to a candidate helper.
+ */
+enum rawrtc_code rawrtc_candidate_helper_stun_session_add(
+ struct rawrtc_candidate_helper_stun_session* const session,
+ struct rawrtc_candidate_helper* const candidate_helper,
+ struct stun_keepalive* const stun_keepalive) {
+ // Check arguments
+ if (!session || !candidate_helper || !stun_keepalive) {
+ return RAWRTC_CODE_INVALID_ARGUMENT;
+ }
+
+ // Set fields/reference
+ session->candidate_helper = mem_ref(candidate_helper);
+ session->stun_keepalive = mem_ref(stun_keepalive);
+
+ // Append to STUN sessions
+ list_append(&candidate_helper->stun_sessions, &session->le, session);
+
+ // Done
+ return RAWRTC_CODE_SUCCESS;
+}
+
+/*
+ * Remove STUN sessions list handler (for candidate helper lists).
+ */
+bool rawrtc_candidate_helper_remove_stun_sessions_handler(struct le* le, void* arg) {
+ struct rawrtc_candidate_helper* const candidate_helper = le->data;
+ (void) arg;
+
+ // Flush STUN sessions
+ list_flush(&candidate_helper->stun_sessions);
+
+ return false; // continue traversing
+}