diff --git a/BUILD b/BUILD
index 6b499737bd5ca10853a8bb151bbfcdb49ded06f5..83335daacc7aaa817bcbabbf24da0dfcf5737969 100644
--- a/BUILD
+++ b/BUILD
@@ -593,6 +593,9 @@ grpc_cc_library(
         "src/core/lib/iomgr/ev_windows.c",
         "src/core/lib/iomgr/exec_ctx.c",
         "src/core/lib/iomgr/executor.c",
+        "src/core/lib/iomgr/gethostname_host_name_max.c",
+        "src/core/lib/iomgr/gethostname_sysconf.c",
+        "src/core/lib/iomgr/gethostname_fallback.c",
         "src/core/lib/iomgr/iocp_windows.c",
         "src/core/lib/iomgr/iomgr.c",
         "src/core/lib/iomgr/iomgr_posix.c",
@@ -718,6 +721,7 @@ grpc_cc_library(
         "src/core/lib/iomgr/ev_posix.h",
         "src/core/lib/iomgr/exec_ctx.h",
         "src/core/lib/iomgr/executor.h",
+        "src/core/lib/iomgr/gethostname.h",
         "src/core/lib/iomgr/iocp_windows.h",
         "src/core/lib/iomgr/iomgr.h",
         "src/core/lib/iomgr/iomgr_internal.h",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6e1b471449deea3494fe4c92cc7cd91f9c0cea86..743b34f11ae1433cb200494c9a97ca5cacd49cae 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -978,6 +978,9 @@ add_library(grpc
   src/core/lib/iomgr/ev_windows.c
   src/core/lib/iomgr/exec_ctx.c
   src/core/lib/iomgr/executor.c
+  src/core/lib/iomgr/gethostname_fallback.c
+  src/core/lib/iomgr/gethostname_host_name_max.c
+  src/core/lib/iomgr/gethostname_sysconf.c
   src/core/lib/iomgr/iocp_windows.c
   src/core/lib/iomgr/iomgr.c
   src/core/lib/iomgr/iomgr_posix.c
@@ -1322,6 +1325,9 @@ add_library(grpc_cronet
   src/core/lib/iomgr/ev_windows.c
   src/core/lib/iomgr/exec_ctx.c
   src/core/lib/iomgr/executor.c
+  src/core/lib/iomgr/gethostname_fallback.c
+  src/core/lib/iomgr/gethostname_host_name_max.c
+  src/core/lib/iomgr/gethostname_sysconf.c
   src/core/lib/iomgr/iocp_windows.c
   src/core/lib/iomgr/iomgr.c
   src/core/lib/iomgr/iomgr_posix.c
@@ -1634,6 +1640,9 @@ add_library(grpc_test_util
   src/core/lib/iomgr/ev_windows.c
   src/core/lib/iomgr/exec_ctx.c
   src/core/lib/iomgr/executor.c
+  src/core/lib/iomgr/gethostname_fallback.c
+  src/core/lib/iomgr/gethostname_host_name_max.c
+  src/core/lib/iomgr/gethostname_sysconf.c
   src/core/lib/iomgr/iocp_windows.c
   src/core/lib/iomgr/iomgr.c
   src/core/lib/iomgr/iomgr_posix.c
@@ -1891,6 +1900,9 @@ add_library(grpc_test_util_unsecure
   src/core/lib/iomgr/ev_windows.c
   src/core/lib/iomgr/exec_ctx.c
   src/core/lib/iomgr/executor.c
+  src/core/lib/iomgr/gethostname_fallback.c
+  src/core/lib/iomgr/gethostname_host_name_max.c
+  src/core/lib/iomgr/gethostname_sysconf.c
   src/core/lib/iomgr/iocp_windows.c
   src/core/lib/iomgr/iomgr.c
   src/core/lib/iomgr/iomgr_posix.c
@@ -2134,6 +2146,9 @@ add_library(grpc_unsecure
   src/core/lib/iomgr/ev_windows.c
   src/core/lib/iomgr/exec_ctx.c
   src/core/lib/iomgr/executor.c
+  src/core/lib/iomgr/gethostname_fallback.c
+  src/core/lib/iomgr/gethostname_host_name_max.c
+  src/core/lib/iomgr/gethostname_sysconf.c
   src/core/lib/iomgr/iocp_windows.c
   src/core/lib/iomgr/iomgr.c
   src/core/lib/iomgr/iomgr_posix.c
@@ -2827,6 +2842,9 @@ add_library(grpc++_cronet
   src/core/lib/iomgr/ev_windows.c
   src/core/lib/iomgr/exec_ctx.c
   src/core/lib/iomgr/executor.c
+  src/core/lib/iomgr/gethostname_fallback.c
+  src/core/lib/iomgr/gethostname_host_name_max.c
+  src/core/lib/iomgr/gethostname_sysconf.c
   src/core/lib/iomgr/iocp_windows.c
   src/core/lib/iomgr/iomgr.c
   src/core/lib/iomgr/iomgr_posix.c
diff --git a/Makefile b/Makefile
index 5168b30e7b951d23e4813cb2732c7080e182e604..af0ca3f1262d884041052eb66257d509ae9fae41 100644
--- a/Makefile
+++ b/Makefile
@@ -2925,6 +2925,9 @@ LIBGRPC_SRC = \
     src/core/lib/iomgr/ev_windows.c \
     src/core/lib/iomgr/exec_ctx.c \
     src/core/lib/iomgr/executor.c \
+    src/core/lib/iomgr/gethostname_fallback.c \
+    src/core/lib/iomgr/gethostname_host_name_max.c \
+    src/core/lib/iomgr/gethostname_sysconf.c \
     src/core/lib/iomgr/iocp_windows.c \
     src/core/lib/iomgr/iomgr.c \
     src/core/lib/iomgr/iomgr_posix.c \
@@ -3267,6 +3270,9 @@ LIBGRPC_CRONET_SRC = \
     src/core/lib/iomgr/ev_windows.c \
     src/core/lib/iomgr/exec_ctx.c \
     src/core/lib/iomgr/executor.c \
+    src/core/lib/iomgr/gethostname_fallback.c \
+    src/core/lib/iomgr/gethostname_host_name_max.c \
+    src/core/lib/iomgr/gethostname_sysconf.c \
     src/core/lib/iomgr/iocp_windows.c \
     src/core/lib/iomgr/iomgr.c \
     src/core/lib/iomgr/iomgr_posix.c \
@@ -3576,6 +3582,9 @@ LIBGRPC_TEST_UTIL_SRC = \
     src/core/lib/iomgr/ev_windows.c \
     src/core/lib/iomgr/exec_ctx.c \
     src/core/lib/iomgr/executor.c \
+    src/core/lib/iomgr/gethostname_fallback.c \
+    src/core/lib/iomgr/gethostname_host_name_max.c \
+    src/core/lib/iomgr/gethostname_sysconf.c \
     src/core/lib/iomgr/iocp_windows.c \
     src/core/lib/iomgr/iomgr.c \
     src/core/lib/iomgr/iomgr_posix.c \
@@ -3822,6 +3831,9 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
     src/core/lib/iomgr/ev_windows.c \
     src/core/lib/iomgr/exec_ctx.c \
     src/core/lib/iomgr/executor.c \
+    src/core/lib/iomgr/gethostname_fallback.c \
+    src/core/lib/iomgr/gethostname_host_name_max.c \
+    src/core/lib/iomgr/gethostname_sysconf.c \
     src/core/lib/iomgr/iocp_windows.c \
     src/core/lib/iomgr/iomgr.c \
     src/core/lib/iomgr/iomgr_posix.c \
@@ -4041,6 +4053,9 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/lib/iomgr/ev_windows.c \
     src/core/lib/iomgr/exec_ctx.c \
     src/core/lib/iomgr/executor.c \
+    src/core/lib/iomgr/gethostname_fallback.c \
+    src/core/lib/iomgr/gethostname_host_name_max.c \
+    src/core/lib/iomgr/gethostname_sysconf.c \
     src/core/lib/iomgr/iocp_windows.c \
     src/core/lib/iomgr/iomgr.c \
     src/core/lib/iomgr/iomgr_posix.c \
@@ -4717,6 +4732,9 @@ LIBGRPC++_CRONET_SRC = \
     src/core/lib/iomgr/ev_windows.c \
     src/core/lib/iomgr/exec_ctx.c \
     src/core/lib/iomgr/executor.c \
+    src/core/lib/iomgr/gethostname_fallback.c \
+    src/core/lib/iomgr/gethostname_host_name_max.c \
+    src/core/lib/iomgr/gethostname_sysconf.c \
     src/core/lib/iomgr/iocp_windows.c \
     src/core/lib/iomgr/iomgr.c \
     src/core/lib/iomgr/iomgr_posix.c \
diff --git a/binding.gyp b/binding.gyp
index 8a2900b01009289f5b1a622b2480fdc7df7e1d30..2ca36e8f69d7ce2f102e2fdeee7f63341d48f07c 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -687,6 +687,9 @@
         'src/core/lib/iomgr/ev_windows.c',
         'src/core/lib/iomgr/exec_ctx.c',
         'src/core/lib/iomgr/executor.c',
+        'src/core/lib/iomgr/gethostname_fallback.c',
+        'src/core/lib/iomgr/gethostname_host_name_max.c',
+        'src/core/lib/iomgr/gethostname_sysconf.c',
         'src/core/lib/iomgr/iocp_windows.c',
         'src/core/lib/iomgr/iomgr.c',
         'src/core/lib/iomgr/iomgr_posix.c',
diff --git a/build.yaml b/build.yaml
index 81bcf4481fb80a7bf1957fe7fd312c36e0f25c52..4c9ec026c5bfb07c988e8d94d262beb495b56ac1 100644
--- a/build.yaml
+++ b/build.yaml
@@ -214,6 +214,9 @@ filegroups:
   - src/core/lib/iomgr/ev_windows.c
   - src/core/lib/iomgr/exec_ctx.c
   - src/core/lib/iomgr/executor.c
+  - src/core/lib/iomgr/gethostname_fallback.c
+  - src/core/lib/iomgr/gethostname_host_name_max.c
+  - src/core/lib/iomgr/gethostname_sysconf.c
   - src/core/lib/iomgr/iocp_windows.c
   - src/core/lib/iomgr/iomgr.c
   - src/core/lib/iomgr/iomgr_posix.c
@@ -359,6 +362,7 @@ filegroups:
   - src/core/lib/iomgr/ev_posix.h
   - src/core/lib/iomgr/exec_ctx.h
   - src/core/lib/iomgr/executor.h
+  - src/core/lib/iomgr/gethostname.h
   - src/core/lib/iomgr/iocp_windows.h
   - src/core/lib/iomgr/iomgr.h
   - src/core/lib/iomgr/iomgr_internal.h
diff --git a/config.m4 b/config.m4
index c5332f13f04b8a98f83d28ad45e6db745ca6ec1c..18671331393638c3b72909d5f0335f767c3d9bba 100644
--- a/config.m4
+++ b/config.m4
@@ -116,6 +116,9 @@ if test "$PHP_GRPC" != "no"; then
     src/core/lib/iomgr/ev_windows.c \
     src/core/lib/iomgr/exec_ctx.c \
     src/core/lib/iomgr/executor.c \
+    src/core/lib/iomgr/gethostname_fallback.c \
+    src/core/lib/iomgr/gethostname_host_name_max.c \
+    src/core/lib/iomgr/gethostname_sysconf.c \
     src/core/lib/iomgr/iocp_windows.c \
     src/core/lib/iomgr/iomgr.c \
     src/core/lib/iomgr/iomgr_posix.c \
diff --git a/config.w32 b/config.w32
index 8529bd549f59106fc1813e97b14eb55acb7ad9bb..03e83b09e83ef446a9d801e82b7fe1ef8076138f 100644
--- a/config.w32
+++ b/config.w32
@@ -93,6 +93,9 @@ if (PHP_GRPC != "no") {
     "src\\core\\lib\\iomgr\\ev_windows.c " +
     "src\\core\\lib\\iomgr\\exec_ctx.c " +
     "src\\core\\lib\\iomgr\\executor.c " +
+    "src\\core\\lib\\iomgr\\gethostname_fallback.c " +
+    "src\\core\\lib\\iomgr\\gethostname_host_name_max.c " +
+    "src\\core\\lib\\iomgr\\gethostname_sysconf.c " +
     "src\\core\\lib\\iomgr\\iocp_windows.c " +
     "src\\core\\lib\\iomgr\\iomgr.c " +
     "src\\core\\lib\\iomgr\\iomgr_posix.c " +
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 11422f56d47bfce350c1e1b1160d00cf7d71809a..bb712313153521b7100edd6b4c011b2821bce340 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -344,6 +344,7 @@ Pod::Spec.new do |s|
                       'src/core/lib/iomgr/ev_posix.h',
                       'src/core/lib/iomgr/exec_ctx.h',
                       'src/core/lib/iomgr/executor.h',
+                      'src/core/lib/iomgr/gethostname.h',
                       'src/core/lib/iomgr/iocp_windows.h',
                       'src/core/lib/iomgr/iomgr.h',
                       'src/core/lib/iomgr/iomgr_internal.h',
@@ -492,6 +493,9 @@ Pod::Spec.new do |s|
                       'src/core/lib/iomgr/ev_windows.c',
                       'src/core/lib/iomgr/exec_ctx.c',
                       'src/core/lib/iomgr/executor.c',
+                      'src/core/lib/iomgr/gethostname_fallback.c',
+                      'src/core/lib/iomgr/gethostname_host_name_max.c',
+                      'src/core/lib/iomgr/gethostname_sysconf.c',
                       'src/core/lib/iomgr/iocp_windows.c',
                       'src/core/lib/iomgr/iomgr.c',
                       'src/core/lib/iomgr/iomgr_posix.c',
@@ -831,6 +835,7 @@ Pod::Spec.new do |s|
                               'src/core/lib/iomgr/ev_posix.h',
                               'src/core/lib/iomgr/exec_ctx.h',
                               'src/core/lib/iomgr/executor.h',
+                              'src/core/lib/iomgr/gethostname.h',
                               'src/core/lib/iomgr/iocp_windows.h',
                               'src/core/lib/iomgr/iomgr.h',
                               'src/core/lib/iomgr/iomgr_internal.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index a4566672acca3e08cad0a2a3985861eb75a1e34a..f4b1fcc6dd9378acc599c60fb975332d542ced89 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -276,6 +276,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/iomgr/ev_posix.h )
   s.files += %w( src/core/lib/iomgr/exec_ctx.h )
   s.files += %w( src/core/lib/iomgr/executor.h )
+  s.files += %w( src/core/lib/iomgr/gethostname.h )
   s.files += %w( src/core/lib/iomgr/iocp_windows.h )
   s.files += %w( src/core/lib/iomgr/iomgr.h )
   s.files += %w( src/core/lib/iomgr/iomgr_internal.h )
@@ -424,6 +425,9 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/iomgr/ev_windows.c )
   s.files += %w( src/core/lib/iomgr/exec_ctx.c )
   s.files += %w( src/core/lib/iomgr/executor.c )
+  s.files += %w( src/core/lib/iomgr/gethostname_fallback.c )
+  s.files += %w( src/core/lib/iomgr/gethostname_host_name_max.c )
+  s.files += %w( src/core/lib/iomgr/gethostname_sysconf.c )
   s.files += %w( src/core/lib/iomgr/iocp_windows.c )
   s.files += %w( src/core/lib/iomgr/iomgr.c )
   s.files += %w( src/core/lib/iomgr/iomgr_posix.c )
diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h
index bb3c90e303e8800d8fbdd000de61e9e1650c9574..2b2036b24f035a2f1a610d9647e6a18702bf40ac 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -258,8 +258,12 @@ typedef struct {
 #define GRPC_ARG_RESOURCE_QUOTA "grpc.resource_quota"
 /** If non-zero, expand wildcard addresses to a list of local addresses. */
 #define GRPC_ARG_EXPAND_WILDCARD_ADDRS "grpc.expand_wildcard_addrs"
-/** Service config data in JSON form. Not intended for use outside of tests. */
+/** Service config data in JSON form.
+    This value will be ignored if the name resolver returns a service config. */
 #define GRPC_ARG_SERVICE_CONFIG "grpc.service_config"
+/** Disable looking up the service config via the name resolver. */
+#define GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION \
+  "grpc.service_config_disable_resolution"
 /** LB policy name. */
 #define GRPC_ARG_LB_POLICY_NAME "grpc.lb_policy_name"
 /** The grpc_socket_mutator instance that set the socket options. A pointer. */
diff --git a/package.xml b/package.xml
index 9bdebe347006b297d8fe9d07140774c3f0d3d8ea..9726d03cc3b4cad9bb1389c9be35070fde5c18d0 100644
--- a/package.xml
+++ b/package.xml
@@ -290,6 +290,7 @@
     <file baseinstalldir="/" name="src/core/lib/iomgr/ev_posix.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/exec_ctx.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/executor.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/gethostname.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iocp_windows.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_internal.h" role="src" />
@@ -438,6 +439,9 @@
     <file baseinstalldir="/" name="src/core/lib/iomgr/ev_windows.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/exec_ctx.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/executor.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/gethostname_fallback.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/gethostname_host_name_max.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/gethostname_sysconf.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iocp_windows.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_posix.c" role="src" />
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c
index 04a7852323d54579004cf03b779a7011638f7b71..f1480bb1ae4a29cec9d6d327c65c14b8fe013b8a 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c
@@ -19,7 +19,10 @@
 #include <grpc/support/port_platform.h>
 #if GRPC_ARES == 1 && !defined(GRPC_UV)
 
+#include <limits.h>
+#include <stdio.h>
 #include <string.h>
+#include <unistd.h>
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/host_port.h>
@@ -31,11 +34,14 @@
 #include "src/core/ext/filters/client_channel/resolver_registry.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/iomgr/combiner.h"
+#include "src/core/lib/iomgr/gethostname.h"
 #include "src/core/lib/iomgr/resolve_address.h"
 #include "src/core/lib/iomgr/timer.h"
+#include "src/core/lib/json/json.h"
 #include "src/core/lib/support/backoff.h"
 #include "src/core/lib/support/env.h"
 #include "src/core/lib/support/string.h"
+#include "src/core/lib/transport/service_config.h"
 
 #define GRPC_DNS_MIN_CONNECT_TIMEOUT_SECONDS 1
 #define GRPC_DNS_INITIAL_CONNECT_BACKOFF_SECONDS 1
@@ -54,6 +60,8 @@ typedef struct {
   char *default_port;
   /** channel args. */
   grpc_channel_args *channel_args;
+  /** whether to request the service config */
+  bool request_service_config;
   /** pollset_set to drive the name resolution process */
   grpc_pollset_set *interested_parties;
 
@@ -85,6 +93,8 @@ typedef struct {
 
   /** currently resolving addresses */
   grpc_lb_addresses *lb_addresses;
+  /** currently resolving service config */
+  char *service_config_json;
 } ares_dns_resolver;
 
 static void dns_ares_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *r);
@@ -144,6 +154,77 @@ static void dns_ares_on_retry_timer_locked(grpc_exec_ctx *exec_ctx, void *arg,
   GRPC_RESOLVER_UNREF(exec_ctx, &r->base, "retry-timer");
 }
 
+static bool value_in_json_array(grpc_json *array, const char *value) {
+  for (grpc_json *entry = array->child; entry != NULL; entry = entry->next) {
+    if (entry->type == GRPC_JSON_STRING && strcmp(entry->value, value) == 0) {
+      return true;
+    }
+  }
+  return false;
+}
+
+static char *choose_service_config(char *service_config_choice_json) {
+  grpc_json *choices_json = grpc_json_parse_string(service_config_choice_json);
+  if (choices_json == NULL || choices_json->type != GRPC_JSON_ARRAY) {
+    gpr_log(GPR_ERROR, "cannot parse service config JSON string");
+    return NULL;
+  }
+  char *service_config = NULL;
+  for (grpc_json *choice = choices_json->child; choice != NULL;
+       choice = choice->next) {
+    if (choice->type != GRPC_JSON_OBJECT) {
+      gpr_log(GPR_ERROR, "cannot parse service config JSON string");
+      break;
+    }
+    grpc_json *service_config_json = NULL;
+    for (grpc_json *field = choice->child; field != NULL; field = field->next) {
+      // Check client language, if specified.
+      if (strcmp(field->key, "clientLanguage") == 0) {
+        if (field->type != GRPC_JSON_ARRAY ||
+            !value_in_json_array(field, "c++")) {
+          service_config_json = NULL;
+          break;
+        }
+      }
+      // Check client hostname, if specified.
+      if (strcmp(field->key, "clientHostname") == 0) {
+        char *hostname = grpc_gethostname();
+        if (hostname == NULL || field->type != GRPC_JSON_ARRAY ||
+            !value_in_json_array(field, hostname)) {
+          service_config_json = NULL;
+          break;
+        }
+      }
+      // Check percentage, if specified.
+      if (strcmp(field->key, "percentage") == 0) {
+        if (field->type != GRPC_JSON_NUMBER) {
+          service_config_json = NULL;
+          break;
+        }
+        int random_pct = rand() % 100;
+        int percentage;
+        if (sscanf(field->value, "%d", &percentage) != 1 ||
+            random_pct > percentage) {
+          service_config_json = NULL;
+          break;
+        }
+      }
+      // Save service config.
+      if (strcmp(field->key, "serviceConfig") == 0) {
+        if (field->type == GRPC_JSON_OBJECT) {
+          service_config_json = field;
+        }
+      }
+    }
+    if (service_config_json != NULL) {
+      service_config = grpc_json_dump_to_string(service_config_json, 0);
+      break;
+    }
+  }
+  grpc_json_destroy(choices_json);
+  return service_config;
+}
+
 static void dns_ares_on_resolved_locked(grpc_exec_ctx *exec_ctx, void *arg,
                                         grpc_error *error) {
   ares_dns_resolver *r = arg;
@@ -152,8 +233,40 @@ static void dns_ares_on_resolved_locked(grpc_exec_ctx *exec_ctx, void *arg,
   r->resolving = false;
   r->pending_request = NULL;
   if (r->lb_addresses != NULL) {
-    grpc_arg new_arg = grpc_lb_addresses_create_channel_arg(r->lb_addresses);
-    result = grpc_channel_args_copy_and_add(r->channel_args, &new_arg, 1);
+    static const char *args_to_remove[2];
+    size_t num_args_to_remove = 0;
+    grpc_arg new_args[3];
+    size_t num_args_to_add = 0;
+    new_args[num_args_to_add++] =
+        grpc_lb_addresses_create_channel_arg(r->lb_addresses);
+    grpc_service_config *service_config = NULL;
+    char *service_config_string = NULL;
+    if (r->service_config_json != NULL) {
+      service_config_string = choose_service_config(r->service_config_json);
+      gpr_free(r->service_config_json);
+      if (service_config_string != NULL) {
+        gpr_log(GPR_INFO, "selected service config choice: %s",
+                service_config_string);
+        args_to_remove[num_args_to_remove++] = GRPC_ARG_SERVICE_CONFIG;
+        new_args[num_args_to_add++] = grpc_channel_arg_string_create(
+            GRPC_ARG_SERVICE_CONFIG, service_config_string);
+        service_config = grpc_service_config_create(service_config_string);
+        if (service_config != NULL) {
+          const char *lb_policy_name =
+              grpc_service_config_get_lb_policy_name(service_config);
+          if (lb_policy_name != NULL) {
+            args_to_remove[num_args_to_remove++] = GRPC_ARG_LB_POLICY_NAME;
+            new_args[num_args_to_add++] = grpc_channel_arg_string_create(
+                GRPC_ARG_LB_POLICY_NAME, (char *)lb_policy_name);
+          }
+        }
+      }
+    }
+    result = grpc_channel_args_copy_and_add_and_remove(
+        r->channel_args, args_to_remove, num_args_to_remove, new_args,
+        num_args_to_add);
+    if (service_config != NULL) grpc_service_config_destroy(service_config);
+    gpr_free(service_config_string);
     grpc_lb_addresses_destroy(exec_ctx, r->lb_addresses);
   } else {
     const char *msg = grpc_error_string(error);
@@ -207,10 +320,12 @@ static void dns_ares_start_resolving_locked(grpc_exec_ctx *exec_ctx,
   GPR_ASSERT(!r->resolving);
   r->resolving = true;
   r->lb_addresses = NULL;
+  r->service_config_json = NULL;
   r->pending_request = grpc_dns_lookup_ares(
       exec_ctx, r->dns_server, r->name_to_resolve, r->default_port,
       r->interested_parties, &r->dns_ares_on_resolved_locked, &r->lb_addresses,
-      true /* check_grpclb */);
+      true /* check_grpclb */,
+      r->request_service_config ? &r->service_config_json : NULL);
 }
 
 static void dns_ares_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
@@ -256,6 +371,10 @@ static grpc_resolver *dns_ares_create(grpc_exec_ctx *exec_ctx,
   r->name_to_resolve = gpr_strdup(path);
   r->default_port = gpr_strdup(default_port);
   r->channel_args = grpc_channel_args_copy(args->args);
+  const grpc_arg *arg = grpc_channel_args_find(
+      r->channel_args, GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION);
+  r->request_service_config = !grpc_channel_arg_get_integer(
+      arg, (grpc_integer_options){false, false, true});
   r->interested_parties = grpc_pollset_set_create();
   if (args->pollset_set != NULL) {
     grpc_pollset_set_add_pollset_set(exec_ctx, r->interested_parties,
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c
index 6ec3790a5fec9d3d6f915ab54e861a89341a0e41..e65723a63be87f5c9419e0ad7f12222878c54377 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c
@@ -54,6 +54,8 @@ struct grpc_ares_request {
   grpc_closure *on_done;
   /** the pointer to receive the resolved addresses */
   grpc_lb_addresses **lb_addrs_out;
+  /** the pointer to receive the service config in JSON */
+  char **service_config_json_out;
   /** the evernt driver used by this request */
   grpc_ares_ev_driver *ev_driver;
   /** number of ongoing queries */
@@ -266,10 +268,68 @@ static void on_srv_query_done_cb(void *arg, int status, int timeouts,
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
+static const char g_service_config_attribute_prefix[] = "grpc_config=";
+
+static void on_txt_done_cb(void *arg, int status, int timeouts,
+                           unsigned char *buf, int len) {
+  gpr_log(GPR_DEBUG, "on_txt_done_cb");
+  char *error_msg;
+  grpc_ares_request *r = (grpc_ares_request *)arg;
+  gpr_mu_lock(&r->mu);
+  if (status != ARES_SUCCESS) goto fail;
+  struct ares_txt_ext *reply = NULL;
+  status = ares_parse_txt_reply_ext(buf, len, &reply);
+  if (status != ARES_SUCCESS) goto fail;
+  // Find service config in TXT record.
+  const size_t prefix_len = sizeof(g_service_config_attribute_prefix) - 1;
+  struct ares_txt_ext *result;
+  for (result = reply; result != NULL; result = result->next) {
+    if (result->record_start &&
+        memcmp(result->txt, g_service_config_attribute_prefix, prefix_len) ==
+            0) {
+      break;
+    }
+  }
+  // Found a service config record.
+  if (result != NULL) {
+    size_t service_config_len = result->length - prefix_len;
+    *r->service_config_json_out = gpr_malloc(service_config_len + 1);
+    memcpy(*r->service_config_json_out, result->txt + prefix_len,
+           service_config_len);
+    for (result = result->next; result != NULL && !result->record_start;
+         result = result->next) {
+      *r->service_config_json_out = gpr_realloc(
+          *r->service_config_json_out, service_config_len + result->length + 1);
+      memcpy(*r->service_config_json_out + service_config_len, result->txt,
+             result->length);
+      service_config_len += result->length;
+    }
+    (*r->service_config_json_out)[service_config_len] = '\0';
+    gpr_log(GPR_INFO, "found service config: %s", *r->service_config_json_out);
+  }
+  // Clean up.
+  ares_free_data(reply);
+  goto done;
+fail:
+  gpr_asprintf(&error_msg, "C-ares TXT lookup status is not ARES_SUCCESS: %s",
+               ares_strerror(status));
+  grpc_error *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg);
+  gpr_free(error_msg);
+  if (r->error == GRPC_ERROR_NONE) {
+    r->error = error;
+  } else {
+    r->error = grpc_error_add_child(error, r->error);
+  }
+done:
+  gpr_mu_unlock(&r->mu);
+  grpc_ares_request_unref(NULL, r);
+}
+
 static grpc_ares_request *grpc_dns_lookup_ares_impl(
     grpc_exec_ctx *exec_ctx, const char *dns_server, const char *name,
     const char *default_port, grpc_pollset_set *interested_parties,
-    grpc_closure *on_done, grpc_lb_addresses **addrs, bool check_grpclb) {
+    grpc_closure *on_done, grpc_lb_addresses **addrs, bool check_grpclb,
+    char **service_config_json) {
   grpc_error *error = GRPC_ERROR_NONE;
   /* TODO(zyc): Enable tracing after #9603 is checked in */
   /* if (grpc_dns_trace) {
@@ -300,11 +360,12 @@ static grpc_ares_request *grpc_dns_lookup_ares_impl(
   error = grpc_ares_ev_driver_create(&ev_driver, interested_parties);
   if (error != GRPC_ERROR_NONE) goto error_cleanup;
 
-  grpc_ares_request *r = gpr_malloc(sizeof(grpc_ares_request));
+  grpc_ares_request *r = gpr_zalloc(sizeof(grpc_ares_request));
   gpr_mu_init(&r->mu);
   r->ev_driver = ev_driver;
   r->on_done = on_done;
   r->lb_addrs_out = addrs;
+  r->service_config_json_out = service_config_json;
   r->success = false;
   r->error = GRPC_ERROR_NONE;
   ares_channel *channel = grpc_ares_ev_driver_get_channel(r->ev_driver);
@@ -315,13 +376,17 @@ static grpc_ares_request *grpc_dns_lookup_ares_impl(
     grpc_resolved_address addr;
     if (grpc_parse_ipv4_hostport(dns_server, &addr, false /* log_errors */)) {
       r->dns_server_addr.family = AF_INET;
-      memcpy(&r->dns_server_addr.addr.addr4, addr.addr, addr.len);
+      struct sockaddr_in *in = (struct sockaddr_in *)addr.addr;
+      memcpy(&r->dns_server_addr.addr.addr4, &in->sin_addr,
+             sizeof(struct in_addr));
       r->dns_server_addr.tcp_port = grpc_sockaddr_get_port(&addr);
       r->dns_server_addr.udp_port = grpc_sockaddr_get_port(&addr);
     } else if (grpc_parse_ipv6_hostport(dns_server, &addr,
                                         false /* log_errors */)) {
       r->dns_server_addr.family = AF_INET6;
-      memcpy(&r->dns_server_addr.addr.addr6, addr.addr, addr.len);
+      struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)addr.addr;
+      memcpy(&r->dns_server_addr.addr.addr6, &in6->sin6_addr,
+             sizeof(struct in6_addr));
       r->dns_server_addr.tcp_port = grpc_sockaddr_get_port(&addr);
       r->dns_server_addr.udp_port = grpc_sockaddr_get_port(&addr);
     } else {
@@ -342,8 +407,6 @@ static grpc_ares_request *grpc_dns_lookup_ares_impl(
       goto error_cleanup;
     }
   }
-  // An extra reference is put here to avoid destroying the request in
-  // on_done_cb before calling grpc_ares_ev_driver_start.
   gpr_ref_init(&r->pending_queries, 1);
   if (grpc_ipv6_loopback_available()) {
     grpc_ares_hostbyname_request *hr = create_hostbyname_request(
@@ -362,6 +425,10 @@ static grpc_ares_request *grpc_dns_lookup_ares_impl(
                r);
     gpr_free(service_name);
   }
+  if (service_config_json != NULL) {
+    grpc_ares_request_ref(r);
+    ares_search(*channel, hr->host, ns_c_in, ns_t_txt, on_txt_done_cb, r);
+  }
   /* TODO(zyc): Handle CNAME records here. */
   grpc_ares_ev_driver_start(exec_ctx, r->ev_driver);
   grpc_ares_request_unref(exec_ctx, r);
@@ -379,8 +446,8 @@ error_cleanup:
 grpc_ares_request *(*grpc_dns_lookup_ares)(
     grpc_exec_ctx *exec_ctx, const char *dns_server, const char *name,
     const char *default_port, grpc_pollset_set *interested_parties,
-    grpc_closure *on_done, grpc_lb_addresses **addrs,
-    bool check_grpclb) = grpc_dns_lookup_ares_impl;
+    grpc_closure *on_done, grpc_lb_addresses **addrs, bool check_grpclb,
+    char **service_config_json) = grpc_dns_lookup_ares_impl;
 
 void grpc_cancel_ares_request(grpc_exec_ctx *exec_ctx, grpc_ares_request *r) {
   if (grpc_dns_lookup_ares == grpc_dns_lookup_ares_impl) {
@@ -465,7 +532,8 @@ static void grpc_resolve_address_ares_impl(grpc_exec_ctx *exec_ctx,
                     grpc_schedule_on_exec_ctx);
   grpc_dns_lookup_ares(exec_ctx, NULL /* dns_server */, name, default_port,
                        interested_parties, &r->on_dns_lookup_done, &r->lb_addrs,
-                       false /* check_grpclb */);
+                       false /* check_grpclb */,
+                       NULL /* service_config_json */);
 }
 
 void (*grpc_resolve_address_ares)(
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
index 5d2d6c993bd3ff8cdb16ebb6ea54f3682600dbc3..108333047d313efe70db925ac73a357efd73835c 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
@@ -27,29 +27,30 @@
 
 typedef struct grpc_ares_request grpc_ares_request;
 
-/* Asynchronously resolve addr. Use \a default_port if a port isn't designated
-   in addr, otherwise use the port in addr. grpc_ares_init() must be called at
-   least once before this function. \a on_done may be called directly in this
-   function without being scheduled with \a exec_ctx, it must not try to acquire
-   locks that are being held by the caller. */
+/* Asynchronously resolve \a name. Use \a default_port if a port isn't
+   designated in \a name, otherwise use the port in \a name. grpc_ares_init()
+   must be called at least once before this function. \a on_done may be
+   called directly in this function without being scheduled with \a exec_ctx,
+   so it must not try to acquire locks that are being held by the caller. */
 extern void (*grpc_resolve_address_ares)(grpc_exec_ctx *exec_ctx,
-                                         const char *addr,
+                                         const char *name,
                                          const char *default_port,
                                          grpc_pollset_set *interested_parties,
                                          grpc_closure *on_done,
                                          grpc_resolved_addresses **addresses);
 
-/* Asynchronously resolve addr. It will try to resolve grpclb SRV records in
+/* Asynchronously resolve \a name. It will try to resolve grpclb SRV records in
   addition to the normal address records. For normal address records, it uses
-  \a default_port if a port isn't designated in \a addr, otherwise it uses the
-  port in \a addr. grpc_ares_init() must be called at least once before this
+  \a default_port if a port isn't designated in \a name, otherwise it uses the
+  port in \a name. grpc_ares_init() must be called at least once before this
   function. \a on_done may be called directly in this function without being
-  scheduled with \a exec_ctx, it must not try to acquire locks that are being
-  held by the caller. */
+  scheduled with \a exec_ctx, so it must not try to acquire locks that are
+  being held by the caller. */
 extern grpc_ares_request *(*grpc_dns_lookup_ares)(
-    grpc_exec_ctx *exec_ctx, const char *dns_server, const char *addr,
+    grpc_exec_ctx *exec_ctx, const char *dns_server, const char *name,
     const char *default_port, grpc_pollset_set *interested_parties,
-    grpc_closure *on_done, grpc_lb_addresses **addresses, bool check_grpclb);
+    grpc_closure *on_done, grpc_lb_addresses **addresses, bool check_grpclb,
+    char **service_config_json);
 
 /* Cancel the pending grpc_ares_request \a request */
 void grpc_cancel_ares_request(grpc_exec_ctx *exec_ctx,
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.c b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.c
index b67636a3e443e17d8c2e239decd29ca22c7aae1e..f2587c4520fc6b42c0a7d7962e10016cc6667da5 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.c
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.c
@@ -28,15 +28,16 @@ struct grpc_ares_request {
 static grpc_ares_request *grpc_dns_lookup_ares_impl(
     grpc_exec_ctx *exec_ctx, const char *dns_server, const char *name,
     const char *default_port, grpc_pollset_set *interested_parties,
-    grpc_closure *on_done, grpc_lb_addresses **addrs, bool check_grpclb) {
+    grpc_closure *on_done, grpc_lb_addresses **addrs, bool check_grpclb,
+    char **service_config_json) {
   return NULL;
 }
 
 grpc_ares_request *(*grpc_dns_lookup_ares)(
     grpc_exec_ctx *exec_ctx, const char *dns_server, const char *name,
     const char *default_port, grpc_pollset_set *interested_parties,
-    grpc_closure *on_done, grpc_lb_addresses **addrs,
-    bool check_grpclb) = grpc_dns_lookup_ares_impl;
+    grpc_closure *on_done, grpc_lb_addresses **addrs, bool check_grpclb,
+    char **service_config_json) = grpc_dns_lookup_ares_impl;
 
 void grpc_cancel_ares_request(grpc_exec_ctx *exec_ctx, grpc_ares_request *r) {}
 
diff --git a/src/core/lib/iomgr/gethostname.h b/src/core/lib/iomgr/gethostname.h
new file mode 100644
index 0000000000000000000000000000000000000000..9c6b9d8d420bae574e3b1f96919f08e49d76322e
--- /dev/null
+++ b/src/core/lib/iomgr/gethostname.h
@@ -0,0 +1,26 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPC_CORE_LIB_IOMGR_GETHOSTNAME_H
+#define GRPC_CORE_LIB_IOMGR_GETHOSTNAME_H
+
+// Returns the hostname of the local machine.
+// Caller takes ownership of result.
+char *grpc_gethostname();
+
+#endif /* GRPC_CORE_LIB_IOMGR_GETHOSTNAME_H */
diff --git a/src/core/lib/iomgr/gethostname_fallback.c b/src/core/lib/iomgr/gethostname_fallback.c
new file mode 100644
index 0000000000000000000000000000000000000000..6229461568b508eb7c73c2dfe725bf86f553587f
--- /dev/null
+++ b/src/core/lib/iomgr/gethostname_fallback.c
@@ -0,0 +1,27 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "src/core/lib/iomgr/port.h"
+
+#ifdef GRPC_GETHOSTNAME_FALLBACK
+
+#include <stddef.h>
+
+char *grpc_gethostname() { return NULL; }
+
+#endif  // GRPC_GETHOSTNAME_FALLBACK
diff --git a/src/core/lib/iomgr/gethostname_host_name_max.c b/src/core/lib/iomgr/gethostname_host_name_max.c
new file mode 100644
index 0000000000000000000000000000000000000000..4d0511412ec4b12f7e993d9a61e89c01bd52d8aa
--- /dev/null
+++ b/src/core/lib/iomgr/gethostname_host_name_max.c
@@ -0,0 +1,37 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "src/core/lib/iomgr/port.h"
+
+#ifdef GRPC_POSIX_HOST_NAME_MAX
+
+#include <limits.h>
+#include <unistd.h>
+
+#include <grpc/support/alloc.h>
+
+char *grpc_gethostname() {
+  char *hostname = (char *)gpr_malloc(HOST_NAME_MAX);
+  if (gethostname(hostname, HOST_NAME_MAX) != 0) {
+    gpr_free(hostname);
+    return NULL;
+  }
+  return hostname;
+}
+
+#endif  // GRPC_POSIX_HOST_NAME_MAX
diff --git a/src/core/lib/iomgr/gethostname_sysconf.c b/src/core/lib/iomgr/gethostname_sysconf.c
new file mode 100644
index 0000000000000000000000000000000000000000..51bac5d69dd8e51c92c5d0e06700340e10ab2376
--- /dev/null
+++ b/src/core/lib/iomgr/gethostname_sysconf.c
@@ -0,0 +1,37 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "src/core/lib/iomgr/port.h"
+
+#ifdef GRPC_POSIX_SYSCONF
+
+#include <unistd.h>
+
+#include <grpc/support/alloc.h>
+
+char *grpc_gethostname() {
+  size_t host_name_max = (size_t)sysconf(_SC_HOST_NAME_MAX);
+  char *hostname = (char *)gpr_malloc(host_name_max);
+  if (gethostname(hostname, host_name_max) != 0) {
+    gpr_free(hostname);
+    return NULL;
+  }
+  return hostname;
+}
+
+#endif  // GRPC_POSIX_SYSCONF
diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h
index c12058f890b118d08fe5767f75f793ded0488deb..42033d0ba4b9d99691bb798e6c35e3af3accf1ec 100644
--- a/src/core/lib/iomgr/port.h
+++ b/src/core/lib/iomgr/port.h
@@ -59,6 +59,7 @@
 #define GRPC_HAVE_MSG_NOSIGNAL 1
 #define GRPC_HAVE_UNIX_SOCKET 1
 #define GRPC_LINUX_MULTIPOLL_WITH_EPOLL 1
+#define GRPC_POSIX_HOST_NAME_MAX 1
 #define GRPC_POSIX_SOCKET 1
 #define GRPC_POSIX_SOCKETADDR 1
 #define GRPC_POSIX_WAKEUP_FD 1
@@ -93,6 +94,7 @@
 #define GRPC_POSIX_SOCKET 1
 #define GRPC_POSIX_SOCKETADDR 1
 #define GRPC_POSIX_SOCKETUTILS 1
+#define GRPC_POSIX_SYSCONF 1
 #define GRPC_POSIX_WAKEUP_FD 1
 #define GRPC_TIMER_USE_GENERIC 1
 #elif defined(GPR_FREEBSD)
@@ -125,4 +127,11 @@
 #error Must define exactly one of GRPC_POSIX_SOCKET, GRPC_WINSOCK_SOCKET, GPR_CUSTOM_SOCKET
 #endif
 
+#if defined(GRPC_POSIX_HOST_NAME_MAX) && defined(GRPC_POSIX_SYSCONF)
+#error "Cannot define both GRPC_POSIX_HOST_NAME_MAX and GRPC_POSIX_SYSCONF"
+#endif
+#if !defined(GRPC_POSIX_HOST_NAME_MAX) && !defined(GRPC_POSIX_SYSCONF)
+#define GRPC_GETHOSTNAME_FALLBACK 1
+#endif
+
 #endif /* GRPC_CORE_LIB_IOMGR_PORT_H */
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index aa074df84928101b5bb95b7734d86206ea306631..e52d43e81dc5a50b1391ba492d7410d8b228353c 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -92,6 +92,9 @@ CORE_SOURCE_FILES = [
   'src/core/lib/iomgr/ev_windows.c',
   'src/core/lib/iomgr/exec_ctx.c',
   'src/core/lib/iomgr/executor.c',
+  'src/core/lib/iomgr/gethostname_fallback.c',
+  'src/core/lib/iomgr/gethostname_host_name_max.c',
+  'src/core/lib/iomgr/gethostname_sysconf.c',
   'src/core/lib/iomgr/iocp_windows.c',
   'src/core/lib/iomgr/iomgr.c',
   'src/core/lib/iomgr/iomgr_posix.c',
diff --git a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
index 6e3d69c2653182a5010a995b5c8ea69d11783f1e..364e1809633aea9b01e72d59bd04aa50157577ba 100644
--- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
+++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
@@ -60,7 +60,8 @@ static void my_resolve_address(grpc_exec_ctx *exec_ctx, const char *addr,
 static grpc_ares_request *my_dns_lookup_ares(
     grpc_exec_ctx *exec_ctx, const char *dns_server, const char *addr,
     const char *default_port, grpc_pollset_set *interested_parties,
-    grpc_closure *on_done, grpc_lb_addresses **lb_addrs, bool check_grpclb) {
+    grpc_closure *on_done, grpc_lb_addresses **lb_addrs, bool check_grpclb,
+    char **service_config_json) {
   gpr_mu_lock(&g_mu);
   GPR_ASSERT(0 == strcmp("test", addr));
   grpc_error *error = GRPC_ERROR_NONE;
diff --git a/test/core/end2end/fuzzers/api_fuzzer.c b/test/core/end2end/fuzzers/api_fuzzer.c
index 01fa4f748f5d84cfefed00f6960d69ca07b49198..1228c9fe9ae48207964ecd05995d3f5752e1b6e4 100644
--- a/test/core/end2end/fuzzers/api_fuzzer.c
+++ b/test/core/end2end/fuzzers/api_fuzzer.c
@@ -416,7 +416,8 @@ void my_resolve_address(grpc_exec_ctx *exec_ctx, const char *addr,
 grpc_ares_request *my_dns_lookup_ares(
     grpc_exec_ctx *exec_ctx, const char *dns_server, const char *addr,
     const char *default_port, grpc_pollset_set *interested_parties,
-    grpc_closure *on_done, grpc_lb_addresses **lb_addrs, bool check_grpclb) {
+    grpc_closure *on_done, grpc_lb_addresses **lb_addrs, bool check_grpclb,
+    char **service_config_json) {
   addr_req *r = gpr_malloc(sizeof(*r));
   r->addr = gpr_strdup(addr);
   r->on_done = on_done;
diff --git a/test/core/end2end/goaway_server_test.c b/test/core/end2end/goaway_server_test.c
index bf90e2525d432933613e1a66c0f6232e062f61f2..c3aca132495983bc967ab6fb047b926361f84fbe 100644
--- a/test/core/end2end/goaway_server_test.c
+++ b/test/core/end2end/goaway_server_test.c
@@ -48,7 +48,8 @@ static void (*iomgr_resolve_address)(grpc_exec_ctx *exec_ctx, const char *addr,
 static grpc_ares_request *(*iomgr_dns_lookup_ares)(
     grpc_exec_ctx *exec_ctx, const char *dns_server, const char *addr,
     const char *default_port, grpc_pollset_set *interested_parties,
-    grpc_closure *on_done, grpc_lb_addresses **addresses, bool check_grpclb);
+    grpc_closure *on_done, grpc_lb_addresses **addresses, bool check_grpclb,
+    char **service_config_json);
 
 static void set_resolve_port(int port) {
   gpr_mu_lock(&g_mu);
@@ -90,11 +91,12 @@ static void my_resolve_address(grpc_exec_ctx *exec_ctx, const char *addr,
 static grpc_ares_request *my_dns_lookup_ares(
     grpc_exec_ctx *exec_ctx, const char *dns_server, const char *addr,
     const char *default_port, grpc_pollset_set *interested_parties,
-    grpc_closure *on_done, grpc_lb_addresses **lb_addrs, bool check_grpclb) {
+    grpc_closure *on_done, grpc_lb_addresses **lb_addrs, bool check_grpclb,
+    char **service_config_json) {
   if (0 != strcmp(addr, "test")) {
     return iomgr_dns_lookup_ares(exec_ctx, dns_server, addr, default_port,
                                  interested_parties, on_done, lb_addrs,
-                                 check_grpclb);
+                                 check_grpclb, service_config_json);
   }
 
   grpc_error *error = GRPC_ERROR_NONE;
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 335243114932ce9f9b96845923acaf4e3b04eb1b..58cd00b264032a03d1c57ed28739a06ae3ef050a 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -959,6 +959,7 @@ src/core/lib/iomgr/ev_poll_posix.h \
 src/core/lib/iomgr/ev_posix.h \
 src/core/lib/iomgr/exec_ctx.h \
 src/core/lib/iomgr/executor.h \
+src/core/lib/iomgr/gethostname.h \
 src/core/lib/iomgr/iocp_windows.h \
 src/core/lib/iomgr/iomgr.h \
 src/core/lib/iomgr/iomgr_internal.h \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 9951edc6782c9a5c9017bc68f15aaa8b05e8f354..8e45f9fe9b6fe41689941767b7ac933b816b5fc3 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -1116,6 +1116,10 @@ src/core/lib/iomgr/exec_ctx.c \
 src/core/lib/iomgr/exec_ctx.h \
 src/core/lib/iomgr/executor.c \
 src/core/lib/iomgr/executor.h \
+src/core/lib/iomgr/gethostname.h \
+src/core/lib/iomgr/gethostname_fallback.c \
+src/core/lib/iomgr/gethostname_host_name_max.c \
+src/core/lib/iomgr/gethostname_sysconf.c \
 src/core/lib/iomgr/iocp_windows.c \
 src/core/lib/iomgr/iocp_windows.h \
 src/core/lib/iomgr/iomgr.c \
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index d5eba6e82d18367c6ad91ef1535818d60d587c79..b666d09b9bcd9b25697d21ffddb5c01e8a7c96d5 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -7833,6 +7833,9 @@
       "src/core/lib/iomgr/ev_windows.c", 
       "src/core/lib/iomgr/exec_ctx.c", 
       "src/core/lib/iomgr/executor.c", 
+      "src/core/lib/iomgr/gethostname_fallback.c", 
+      "src/core/lib/iomgr/gethostname_host_name_max.c", 
+      "src/core/lib/iomgr/gethostname_sysconf.c", 
       "src/core/lib/iomgr/iocp_windows.c", 
       "src/core/lib/iomgr/iomgr.c", 
       "src/core/lib/iomgr/iomgr_posix.c", 
@@ -7979,6 +7982,7 @@
       "src/core/lib/iomgr/ev_posix.h", 
       "src/core/lib/iomgr/exec_ctx.h", 
       "src/core/lib/iomgr/executor.h", 
+      "src/core/lib/iomgr/gethostname.h", 
       "src/core/lib/iomgr/iocp_windows.h", 
       "src/core/lib/iomgr/iomgr.h", 
       "src/core/lib/iomgr/iomgr_internal.h", 
@@ -8107,6 +8111,7 @@
       "src/core/lib/iomgr/ev_posix.h", 
       "src/core/lib/iomgr/exec_ctx.h", 
       "src/core/lib/iomgr/executor.h", 
+      "src/core/lib/iomgr/gethostname.h", 
       "src/core/lib/iomgr/iocp_windows.h", 
       "src/core/lib/iomgr/iomgr.h", 
       "src/core/lib/iomgr/iomgr_internal.h", 
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
index 625c62adcd6bf2ce6dae3fb7087931bb118d886e..7c8f35a89530fa5f333ff0b95907f59a0a8dd5d5 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
@@ -450,6 +450,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\exec_ctx.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_internal.h" />
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
index ff9913a362ad3bfb7dfe587696ef6d866fed41ef..d969553f0ec390bfc535fe73d1d86aa67d9b75d2 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
@@ -701,6 +701,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
index baeb6e35b2d0244ec73b33235671a093d8c6d5a6..f147ac33381f24ffd6c8849affd735af32389e69 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
@@ -444,6 +444,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\exec_ctx.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_internal.h" />
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
index 5820ce041419a26c0c1bd5633dee69657081a25c..a49d48fe218266cc3bf7bffea13b919c0124bceb 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
@@ -668,6 +668,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index 3f711f690f8d843919e1ecd25217ce4cf11ed1c8..5cb0d3fc6295a441a794dfafa5941caba5374b38 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -401,6 +401,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\exec_ctx.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_internal.h" />
@@ -582,6 +583,12 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname_fallback.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname_host_name_max.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname_sysconf.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr.c">
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index 662eddfc52527a71d06bfbbcc0edae5e01780d66..2b3d085f29a8157989ace181e889c84b94d062c5 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -94,6 +94,15 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname_fallback.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname_host_name_max.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname_sysconf.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
@@ -1163,6 +1172,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
index fa31dbe3e19fa400779bcc0aaa38ff7ebd3fde94..1766e2445d7d973bafa3c1eb1eec0ae907065653 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
@@ -329,6 +329,12 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname_fallback.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname_host_name_max.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname_sysconf.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr.c">
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
index fc9f64a6146be322eeb215ae547fc99821c5683c..8516a07196d19e42ab1c84082d9adc99b3f30835 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
@@ -151,6 +151,15 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname_fallback.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname_host_name_max.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname_sysconf.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
diff --git a/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj b/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj
index 457dbd57c74601dd7f643cdcc09cebcc5b6b69af..c92f0d123783a8e3d4c13ec56025356281ea6e4a 100644
--- a/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj
@@ -317,6 +317,12 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname_fallback.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname_host_name_max.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname_sysconf.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr.c">
diff --git a/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters
index 49e886de3def3e1b685cab43a454a650f23fcaee..df34bdba88d77e3be8dc00fc6a2891a7d33ba5ce 100644
--- a/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters
@@ -136,6 +136,15 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname_fallback.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname_host_name_max.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname_sysconf.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
index c0ce8f0a4be6df43d8d1f075765ada6b7fdf915c..afc6ac80f97678d6c335946c055273dca7c3b90d 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -365,6 +365,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\exec_ctx.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_internal.h" />
@@ -548,6 +549,12 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname_fallback.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname_host_name_max.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname_sysconf.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr.c">
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index 2d2a8200e0a94ea088b155276d13c6525555d1de..f0aded8826d042dce288b87c1c56920bc6f52e52 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -97,6 +97,15 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname_fallback.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname_host_name_max.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname_sysconf.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
@@ -992,6 +1001,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\gethostname.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>