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;
+}