diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c
index cd55520c..dade1846 100644
--- a/src/core/ngx_resolver.c
+++ b/src/core/ngx_resolver.c
@@ -9,12 +9,26 @@
 #include <ngx_core.h>
 #include <ngx_event.h>
 
+#if !(NGX_WIN32)
+#include <resolv.h>
+#endif
+
 
 #define NGX_RESOLVER_UDP_SIZE   4096
 
 #define NGX_RESOLVER_TCP_RSIZE  (2 + 65535)
 #define NGX_RESOLVER_TCP_WSIZE  8192
 
+#if !(NGX_WIN32)
+/*
+ * note that 2KB should be more than enough for majority of the
+ * resolv.conf files out there. it also acts as a safety guard to prevent
+ * abuse.
+ */
+#define NGX_RESOLVER_FILE_BUF_SIZE  2048
+#define NGX_RESOLVER_FILE_NAME      "/etc/resolv.conf"
+#endif
+
 
 typedef struct {
     u_char  ident_hi;
@@ -131,6 +145,191 @@ static ngx_resolver_node_t *ngx_resolver_lookup_addr6(ngx_resolver_t *r,
 #endif
 
 
+#if !(NGX_WIN32)
+static ngx_int_t
+ngx_resolver_read_resolv_conf(ngx_conf_t *cf, ngx_resolver_t *r, u_char *path,
+    size_t path_len)
+{
+    ngx_url_t                        u;
+    ngx_resolver_connection_t       *rec;
+    ngx_fd_t                         fd;
+    ngx_file_t                       file;
+    u_char                           buf[NGX_RESOLVER_FILE_BUF_SIZE];
+    u_char                           ipv6_buf[NGX_INET6_ADDRSTRLEN];
+    ngx_uint_t                       address = 0, j, total = 0;
+    ssize_t                          n, i;
+    enum {
+        sw_nameserver,
+        sw_spaces,
+        sw_address,
+        sw_skip
+    } state;
+
+    file.name.data = path;
+    file.name.len = path_len;
+
+    if (ngx_conf_full_name(cf->cycle, &file.name, 1) != NGX_OK) {
+        return NGX_ERROR;
+    }
+
+    fd = ngx_open_file(file.name.data, NGX_FILE_RDONLY,
+                       NGX_FILE_OPEN, 0);
+
+    if (fd == NGX_INVALID_FILE) {
+        ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
+                           ngx_open_file_n " \"%s\" failed", file.name.data);
+
+        return NGX_ERROR;
+    }
+
+    ngx_memzero(&file, sizeof(ngx_file_t));
+
+    file.fd = fd;
+    file.log = cf->log;
+
+    state = sw_nameserver;
+
+    n = ngx_read_file(&file, buf, NGX_RESOLVER_FILE_BUF_SIZE, 0);
+
+    if (n == NGX_ERROR) {
+        ngx_conf_log_error(NGX_LOG_ALERT, cf, ngx_errno,
+                           ngx_read_file_n " \"%s\" failed", file.name.data);
+    }
+
+    if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
+        ngx_conf_log_error(NGX_LOG_ALERT, cf, ngx_errno,
+                           ngx_close_file_n " \"%s\" failed", file.name.data);
+    }
+
+    if (n == NGX_ERROR) {
+        return NGX_ERROR;
+    }
+
+    if (n == 0) {
+        return NGX_OK;
+    }
+
+    for (i = 0; i < n && total < MAXNS; /* void */) {
+        if (buf[i] == '#' || buf[i] == ';') {
+            state = sw_skip;
+        }
+
+        switch (state) {
+
+        case sw_nameserver:
+
+            if ((size_t) n - i >= sizeof("nameserver") - 1
+                && ngx_memcmp(buf + i, "nameserver",
+                              sizeof("nameserver") - 1) == 0)
+            {
+                state = sw_spaces;
+                i += sizeof("nameserver") - 1;
+
+                continue;
+            }
+
+            break;
+
+        case sw_spaces:
+            if (buf[i] != '\t' && buf[i] != ' ') {
+                address = i;
+                state = sw_address;
+            }
+
+            break;
+
+        case sw_address:
+
+            if (buf[i] == CR || buf[i] == LF || i == n - 1) {
+                ngx_memzero(&u, sizeof(ngx_url_t));
+
+                u.url.data = buf + address;
+
+                if (i == n - 1 && buf[i] != CR && buf[i] != LF) {
+                    u.url.len = n - address;
+
+                } else {
+                    u.url.len = i - address;
+                }
+
+                u.default_port = 53;
+
+                /* IPv6? */
+                if (ngx_strlchr(u.url.data, u.url.data + u.url.len,
+                                ':') != NULL)
+                {
+                    if (u.url.len + 2 > sizeof(ipv6_buf)) {
+                        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                                           "IPv6 resolver address is too long:"
+                                           " \"%V\"", &u.url);
+
+                        return NGX_ERROR;
+                    }
+
+                    ipv6_buf[0] = '[';
+                    ngx_memcpy(ipv6_buf + 1, u.url.data, u.url.len);
+                    ipv6_buf[u.url.len + 1] = ']';
+
+                    u.url.data = ipv6_buf;
+                    u.url.len = u.url.len + 2;
+                }
+
+                if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
+                    if (u.err) {
+                        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                                           "%s in resolver \"%V\"",
+                                           u.err, &u.url);
+                    }
+
+                    return NGX_ERROR;
+                }
+
+                rec = ngx_array_push_n(&r->connections, u.naddrs);
+                if (rec == NULL) {
+                    return NGX_ERROR;
+                }
+
+                ngx_memzero(rec, u.naddrs * sizeof(ngx_resolver_connection_t));
+
+                for (j = 0; j < u.naddrs; j++) {
+                    rec[j].sockaddr = u.addrs[j].sockaddr;
+                    rec[j].socklen = u.addrs[j].socklen;
+                    rec[j].server = u.addrs[j].name;
+                    rec[j].resolver = r;
+                }
+
+                total++;
+
+#if (NGX_DEBUG)
+                /*
+                 * logs with level below NGX_LOG_NOTICE will not be printed
+                 * in this early phase
+                 */
+                ngx_conf_log_error(NGX_LOG_NOTICE, cf, 0,
+                                   "parsed a resolver: \"%V\"", &u.url);
+#endif
+
+                state = sw_nameserver;
+            }
+
+            break;
+
+        case sw_skip:
+            if (buf[i] == CR || buf[i] == LF) {
+                state = sw_nameserver;
+            }
+
+            break;
+        }
+
+        i++;
+    }
+
+    return NGX_OK;
+}
+#endif
+
+
 ngx_resolver_t *
 ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n)
 {
@@ -246,6 +445,39 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n)
         }
 #endif
 
+#if !(NGX_WIN32)
+        if (ngx_strncmp(names[i].data, "local=", 6) == 0) {
+
+            if (ngx_strcmp(&names[i].data[6], "on") == 0) {
+                if (ngx_resolver_read_resolv_conf(cf, r,
+                                                  (u_char *)
+                                                  NGX_RESOLVER_FILE_NAME,
+                                                  sizeof(NGX_RESOLVER_FILE_NAME)
+                                                  - 1)
+                    != NGX_OK)
+                {
+                    ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                                       "unable to parse local resolver");
+                    return NULL;
+                }
+
+            } else if (ngx_strcmp(&names[i].data[6], "off") != 0) {
+                if (ngx_resolver_read_resolv_conf(cf, r,
+                                                  &names[i].data[6],
+                                                  names[i].len - 6)
+                    != NGX_OK)
+                {
+                    ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                                       "unable to parse local resolver");
+                    return NULL;
+                }
+
+            }
+
+            continue;
+        }
+#endif
+
         ngx_memzero(&u, sizeof(ngx_url_t));
 
         u.url = names[i];