Squashed 'third_party/rawrtc/rew/' content from commit 24c91fd83
Change-Id: Ica2fcc790472ecd5b195d20da982c4e84139cbdd
git-subtree-dir: third_party/rawrtc/rew
git-subtree-split: 24c91fd839b40b11f727c902fa46d20874da33fb
diff --git a/src/trice/rcand.c b/src/trice/rcand.c
new file mode 100644
index 0000000..9516699
--- /dev/null
+++ b/src/trice/rcand.c
@@ -0,0 +1,205 @@
+/**
+ * @file rcand.c Remote ICE Candidates
+ *
+ * Copyright (C) 2010 - 2015 Creytiv.com
+ */
+#include <string.h>
+#include <re_types.h>
+#include <re_fmt.h>
+#include <re_mem.h>
+#include <re_mbuf.h>
+#include <re_list.h>
+#include <re_tmr.h>
+#include <re_sa.h>
+#include <re_net.h>
+#include <re_stun.h>
+#include <re_ice.h>
+#include <re_trice.h>
+#include "trice.h"
+
+
+#define DEBUG_MODULE "rcand"
+#define DEBUG_LEVEL 5
+#include <re_dbg.h>
+
+
+static void rcand_destructor(void *data)
+{
+ struct ice_rcand *cand = data;
+
+ list_unlink(&cand->le);
+}
+
+
+static int trice_add_rcandidate(struct ice_rcand **candp,
+ struct list *lst,
+ unsigned compid, const char *foundation,
+ int proto,
+ uint32_t prio, const struct sa *addr,
+ enum ice_cand_type type,
+ enum ice_tcptype tcptype)
+{
+ struct ice_rcand *cand;
+ int err = 0;
+
+ if (!lst || !compid || !foundation || !proto || !addr)
+ return EINVAL;
+
+ cand = mem_zalloc(sizeof(*cand), rcand_destructor);
+ if (!cand)
+ return ENOMEM;
+
+ cand->attr.compid = compid;
+ str_ncpy(cand->attr.foundation, foundation,
+ sizeof(cand->attr.foundation));
+ cand->attr.proto = proto;
+ cand->attr.prio = prio;
+ cand->attr.addr = *addr;
+ cand->attr.type = type;
+ cand->attr.tcptype = tcptype;
+
+ if (err)
+ goto out;
+
+ list_append(lst, &cand->le, cand);
+
+ out:
+ if (err)
+ mem_deref(cand);
+ else if (candp)
+ *candp = cand;
+
+ return err;
+}
+
+
+/* you can call this at any time */
+int trice_rcand_add(struct ice_rcand **rcandp, struct trice *icem,
+ unsigned compid, const char *foundation,
+ int proto, uint32_t prio,
+ const struct sa *addr, enum ice_cand_type type,
+ enum ice_tcptype tcptype)
+{
+ struct ice_rcand *rcand;
+ int sa_flags = SA_ADDR;
+ int err = 0;
+
+ if (!icem || !foundation)
+ return EINVAL;
+
+ if (proto == IPPROTO_UDP)
+ sa_flags |= SA_PORT;
+
+ if (proto == IPPROTO_TCP &&
+ (tcptype == ICE_TCP_PASSIVE || tcptype == ICE_TCP_SO))
+ sa_flags |= SA_PORT;
+
+ if (!sa_isset(addr, sa_flags)) {
+ DEBUG_WARNING("add_remote_candidate: invalid address"
+ " (%J) for %s.%s\n",
+ addr, net_proto2name(proto),
+ ice_tcptype_name(tcptype));
+ return EINVAL;
+ }
+
+ /* avoid duplicates */
+ rcand = trice_rcand_find(icem, compid, proto, addr);
+ if (rcand) {
+
+ if (rcand->attr.type == ICE_CAND_TYPE_PRFLX &&
+ prio > rcand->attr.prio) {
+
+ rcand->attr.type = type;
+ rcand->attr.prio = prio;
+ }
+
+ goto out;
+ }
+
+ err = trice_add_rcandidate(&rcand, &icem->rcandl,
+ compid, foundation,
+ proto, prio, addr, type, tcptype);
+ if (err)
+ goto out;
+
+ if (icem->lrole != ICE_ROLE_UNKNOWN) {
+ /* pair this remote-candidate with all existing
+ * local-candidates */
+ err = trice_candpair_with_remote(icem, rcand);
+ if (err)
+ goto out;
+
+ /* new pair -- refresh the checklist timer */
+ trice_checklist_refresh(icem);
+ }
+
+ out:
+ if (err)
+ mem_deref(rcand);
+ else if (rcandp)
+ *rcandp = rcand;
+
+ return err;
+}
+
+
+struct ice_rcand *trice_rcand_find(struct trice *icem,
+ unsigned compid, int proto,
+ const struct sa *addr)
+{
+ struct list *lst;
+ struct le *le;
+
+ if (!icem)
+ return NULL;
+
+ if (!proto) {
+ DEBUG_WARNING("find_candidate: invalid args\n");
+ return NULL;
+ }
+
+ lst = &icem->rcandl;
+
+ for (le = list_head(lst); le; le = le->next) {
+
+ struct ice_cand_attr *cand = le->data;
+
+ if (compid && cand->compid != compid)
+ continue;
+
+ if (cand->proto != proto)
+ continue;
+
+ if (addr && !sa_cmp(&cand->addr, addr, SA_ALL))
+ continue;
+
+ return (void *)cand;
+ }
+
+ return NULL;
+}
+
+
+int trice_rcands_debug(struct re_printf *pf, const struct list *lst)
+{
+ struct le *le;
+ int err;
+
+ err = re_hprintf(pf, " (%u)\n", list_count(lst));
+
+ for (le = list_head(lst); le && !err; le = le->next) {
+
+ const struct ice_rcand *rcand = le->data;
+
+ err |= re_hprintf(pf, " {%u} "
+ "fnd=%-8s prio=%08x %24H",
+ rcand->attr.compid,
+ rcand->attr.foundation,
+ rcand->attr.prio,
+ trice_cand_print, rcand);
+
+ err |= re_hprintf(pf, "\n");
+ }
+
+ return err;
+}