Squashed 'third_party/rawrtc/re/' content from commit f3163ce8b

Change-Id: I6a235e6ac0f03269d951026f9d195da05c40fdab
git-subtree-dir: third_party/rawrtc/re
git-subtree-split: f3163ce8b526a13b35ef71ce4dd6f43585064d8a
diff --git a/src/dns/ns.c b/src/dns/ns.c
new file mode 100644
index 0000000..aac713d
--- /dev/null
+++ b/src/dns/ns.c
@@ -0,0 +1,150 @@
+/**
+ * @file ns.c  DNS Nameserver configuration
+ *
+ * Copyright (C) 2010 Creytiv.com
+ */
+#include <stdio.h>
+#include <re_types.h>
+#include <re_fmt.h>
+#include <re_mbuf.h>
+#include <re_list.h>
+#include <re_sa.h>
+#include <re_dns.h>
+#include "dns.h"
+#ifdef __ANDROID__
+#include <sys/system_properties.h>
+#endif
+
+
+#define DEBUG_MODULE "ns"
+#define DEBUG_LEVEL 5
+#include <re_dbg.h>
+
+
+static int parse_resolv_conf(char *domain, size_t dsize,
+			     struct sa *srvv, uint32_t *n)
+{
+	FILE *f;
+	struct pl dom = pl_null;
+	uint32_t i = 0;
+	int err = 0;
+
+	if (!srvv || !n || !*n)
+		return EINVAL;
+
+	f = fopen("/etc/resolv.conf", "r");
+	if (!f)
+		return errno;
+
+	for (;;) {
+		char line[128];
+		struct pl srv;
+		size_t len;
+
+		if (1 != fscanf(f, "%127[^\n]\n", line))
+			break;
+
+		if ('#' == line[0])
+			continue;
+
+		len = str_len(line);
+
+		/* Set domain if not already set */
+		if (!pl_isset(&dom)) {
+			if (0 == re_regex(line, len, "domain [^ ]+", &dom)) {
+				(void)pl_strcpy(&dom, domain, dsize);
+			}
+
+			if (0 == re_regex(line, len, "search [^ ]+", &dom)) {
+				(void)pl_strcpy(&dom, domain, dsize);
+			}
+		}
+
+		/* Use the first entry */
+		if (i < *n && 0 == re_regex(line, len, "nameserver [^\n]+",
+					    &srv)) {
+			err = sa_set(&srvv[i], &srv, DNS_PORT);
+			if (err) {
+				DEBUG_WARNING("sa_set: %r (%m)\n", &srv, err);
+			}
+			++i;
+		}
+	}
+
+	*n = i;
+
+	(void)fclose(f);
+
+	return err;
+}
+
+
+#ifdef __ANDROID__
+static int get_android_dns(struct sa *nsv, uint32_t *n)
+{
+	char prop[PROP_NAME_MAX] = {0}, value[PROP_VALUE_MAX] = {0};
+	uint32_t i, count = 0;
+	int err;
+
+	for (i=0; i<*n; i++) {
+		re_snprintf(prop, sizeof(prop), "net.dns%u", 1+i);
+
+		if (__system_property_get(prop, value)) {
+
+			err = sa_set_str(&nsv[count], value, DNS_PORT);
+			if (!err)
+				++count;
+		}
+	}
+	if (count == 0)
+		return ENOENT;
+
+	*n = count;
+
+	return 0;
+}
+#endif
+
+
+/**
+ * Get the DNS domain and nameservers
+ *
+ * @param domain Returned domain name
+ * @param dsize  Size of domain name buffer
+ * @param srvv   Returned nameservers
+ * @param n      Nameservers capacity, actual on return
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int dns_srv_get(char *domain, size_t dsize, struct sa *srvv, uint32_t *n)
+{
+	int err;
+
+	/* Try them all in prioritized order */
+
+#ifdef HAVE_RESOLV
+	err = get_resolv_dns(domain, dsize, srvv, n);
+	if (!err)
+		return 0;
+#endif
+
+#ifdef DARWIN
+	err = get_darwin_dns(domain, dsize, srvv, n);
+	if (!err)
+		return 0;
+#endif
+
+	err = parse_resolv_conf(domain, dsize, srvv, n);
+	if (!err)
+		return 0;
+
+#ifdef WIN32
+	err = get_windns(domain, dsize, srvv, n);
+#endif
+
+#ifdef __ANDROID__
+	err = get_android_dns(srvv, n);
+#endif
+
+	return err;
+}