diff --git a/BUILD b/BUILD
index 894c7b2c6d549a7466b53cd3f39ef04062f89620..e73b32ded719e01b13482b62172ebfd787b28ee0 100644
--- a/BUILD
+++ b/BUILD
@@ -203,6 +203,7 @@ cc_library(
     "src/core/lib/iomgr/sockaddr_posix.h",
     "src/core/lib/iomgr/sockaddr_utils.h",
     "src/core/lib/iomgr/sockaddr_windows.h",
+    "src/core/lib/iomgr/socket_mutator.h",
     "src/core/lib/iomgr/socket_utils.h",
     "src/core/lib/iomgr/socket_utils_posix.h",
     "src/core/lib/iomgr/socket_windows.h",
@@ -376,6 +377,7 @@ cc_library(
     "src/core/lib/iomgr/resolve_address_windows.c",
     "src/core/lib/iomgr/resource_quota.c",
     "src/core/lib/iomgr/sockaddr_utils.c",
+    "src/core/lib/iomgr/socket_mutator.c",
     "src/core/lib/iomgr/socket_utils_common_posix.c",
     "src/core/lib/iomgr/socket_utils_linux.c",
     "src/core/lib/iomgr/socket_utils_posix.c",
@@ -637,6 +639,7 @@ cc_library(
     "src/core/lib/iomgr/sockaddr_posix.h",
     "src/core/lib/iomgr/sockaddr_utils.h",
     "src/core/lib/iomgr/sockaddr_windows.h",
+    "src/core/lib/iomgr/socket_mutator.h",
     "src/core/lib/iomgr/socket_utils.h",
     "src/core/lib/iomgr/socket_utils_posix.h",
     "src/core/lib/iomgr/socket_windows.h",
@@ -795,6 +798,7 @@ cc_library(
     "src/core/lib/iomgr/resolve_address_windows.c",
     "src/core/lib/iomgr/resource_quota.c",
     "src/core/lib/iomgr/sockaddr_utils.c",
+    "src/core/lib/iomgr/socket_mutator.c",
     "src/core/lib/iomgr/socket_utils_common_posix.c",
     "src/core/lib/iomgr/socket_utils_linux.c",
     "src/core/lib/iomgr/socket_utils_posix.c",
@@ -1026,6 +1030,7 @@ cc_library(
     "src/core/lib/iomgr/sockaddr_posix.h",
     "src/core/lib/iomgr/sockaddr_utils.h",
     "src/core/lib/iomgr/sockaddr_windows.h",
+    "src/core/lib/iomgr/socket_mutator.h",
     "src/core/lib/iomgr/socket_utils.h",
     "src/core/lib/iomgr/socket_utils_posix.h",
     "src/core/lib/iomgr/socket_windows.h",
@@ -1176,6 +1181,7 @@ cc_library(
     "src/core/lib/iomgr/resolve_address_windows.c",
     "src/core/lib/iomgr/resource_quota.c",
     "src/core/lib/iomgr/sockaddr_utils.c",
+    "src/core/lib/iomgr/socket_mutator.c",
     "src/core/lib/iomgr/socket_utils_common_posix.c",
     "src/core/lib/iomgr/socket_utils_linux.c",
     "src/core/lib/iomgr/socket_utils_posix.c",
@@ -2037,6 +2043,7 @@ objc_library(
     "src/core/lib/iomgr/resolve_address_windows.c",
     "src/core/lib/iomgr/resource_quota.c",
     "src/core/lib/iomgr/sockaddr_utils.c",
+    "src/core/lib/iomgr/socket_mutator.c",
     "src/core/lib/iomgr/socket_utils_common_posix.c",
     "src/core/lib/iomgr/socket_utils_linux.c",
     "src/core/lib/iomgr/socket_utils_posix.c",
@@ -2277,6 +2284,7 @@ objc_library(
     "src/core/lib/iomgr/sockaddr_posix.h",
     "src/core/lib/iomgr/sockaddr_utils.h",
     "src/core/lib/iomgr/sockaddr_windows.h",
+    "src/core/lib/iomgr/socket_mutator.h",
     "src/core/lib/iomgr/socket_utils.h",
     "src/core/lib/iomgr/socket_utils_posix.h",
     "src/core/lib/iomgr/socket_windows.h",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 98d54f2198139ca9f5a8c94063a89329ef07089c..3ea99983410e77ee655a90e47db37b60b1826b4c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -331,6 +331,7 @@ add_library(grpc
   src/core/lib/iomgr/resolve_address_windows.c
   src/core/lib/iomgr/resource_quota.c
   src/core/lib/iomgr/sockaddr_utils.c
+  src/core/lib/iomgr/socket_mutator.c
   src/core/lib/iomgr/socket_utils_common_posix.c
   src/core/lib/iomgr/socket_utils_linux.c
   src/core/lib/iomgr/socket_utils_posix.c
@@ -610,6 +611,7 @@ add_library(grpc_cronet
   src/core/lib/iomgr/resolve_address_windows.c
   src/core/lib/iomgr/resource_quota.c
   src/core/lib/iomgr/sockaddr_utils.c
+  src/core/lib/iomgr/socket_mutator.c
   src/core/lib/iomgr/socket_utils_common_posix.c
   src/core/lib/iomgr/socket_utils_linux.c
   src/core/lib/iomgr/socket_utils_posix.c
@@ -861,6 +863,7 @@ add_library(grpc_unsecure
   src/core/lib/iomgr/resolve_address_windows.c
   src/core/lib/iomgr/resource_quota.c
   src/core/lib/iomgr/sockaddr_utils.c
+  src/core/lib/iomgr/socket_mutator.c
   src/core/lib/iomgr/socket_utils_common_posix.c
   src/core/lib/iomgr/socket_utils_linux.c
   src/core/lib/iomgr/socket_utils_posix.c
diff --git a/Makefile b/Makefile
index 56c05f15856cb4c8d2c09b8df47ad7a5ee08786a..351abdaada86c43d2549d360fdfe81826f1125c5 100644
--- a/Makefile
+++ b/Makefile
@@ -2665,6 +2665,7 @@ LIBGRPC_SRC = \
     src/core/lib/iomgr/resolve_address_windows.c \
     src/core/lib/iomgr/resource_quota.c \
     src/core/lib/iomgr/sockaddr_utils.c \
+    src/core/lib/iomgr/socket_mutator.c \
     src/core/lib/iomgr/socket_utils_common_posix.c \
     src/core/lib/iomgr/socket_utils_linux.c \
     src/core/lib/iomgr/socket_utils_posix.c \
@@ -2962,6 +2963,7 @@ LIBGRPC_CRONET_SRC = \
     src/core/lib/iomgr/resolve_address_windows.c \
     src/core/lib/iomgr/resource_quota.c \
     src/core/lib/iomgr/sockaddr_utils.c \
+    src/core/lib/iomgr/socket_mutator.c \
     src/core/lib/iomgr/socket_utils_common_posix.c \
     src/core/lib/iomgr/socket_utils_linux.c \
     src/core/lib/iomgr/socket_utils_posix.c \
@@ -3250,6 +3252,7 @@ LIBGRPC_TEST_UTIL_SRC = \
     src/core/lib/iomgr/resolve_address_windows.c \
     src/core/lib/iomgr/resource_quota.c \
     src/core/lib/iomgr/sockaddr_utils.c \
+    src/core/lib/iomgr/socket_mutator.c \
     src/core/lib/iomgr/socket_utils_common_posix.c \
     src/core/lib/iomgr/socket_utils_linux.c \
     src/core/lib/iomgr/socket_utils_posix.c \
@@ -3467,6 +3470,7 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/lib/iomgr/resolve_address_windows.c \
     src/core/lib/iomgr/resource_quota.c \
     src/core/lib/iomgr/sockaddr_utils.c \
+    src/core/lib/iomgr/socket_mutator.c \
     src/core/lib/iomgr/socket_utils_common_posix.c \
     src/core/lib/iomgr/socket_utils_linux.c \
     src/core/lib/iomgr/socket_utils_posix.c \
diff --git a/binding.gyp b/binding.gyp
index ba90fcaa1003116fdaa0056223b72df8373d7276..11a2e2884e9646c84e854f64eaec26167dac2821 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -611,6 +611,7 @@
         'src/core/lib/iomgr/resolve_address_windows.c',
         'src/core/lib/iomgr/resource_quota.c',
         'src/core/lib/iomgr/sockaddr_utils.c',
+        'src/core/lib/iomgr/socket_mutator.c',
         'src/core/lib/iomgr/socket_utils_common_posix.c',
         'src/core/lib/iomgr/socket_utils_linux.c',
         'src/core/lib/iomgr/socket_utils_posix.c',
diff --git a/build.yaml b/build.yaml
index 41c0f9a08633922d22898303afcea829966b94d9..518484134b96b99cc0ff5bb2d952cd0028cc43a3 100644
--- a/build.yaml
+++ b/build.yaml
@@ -210,6 +210,7 @@ filegroups:
   - src/core/lib/iomgr/sockaddr_posix.h
   - src/core/lib/iomgr/sockaddr_utils.h
   - src/core/lib/iomgr/sockaddr_windows.h
+  - src/core/lib/iomgr/socket_mutator.h
   - src/core/lib/iomgr/socket_utils.h
   - src/core/lib/iomgr/socket_utils_posix.h
   - src/core/lib/iomgr/socket_windows.h
@@ -307,6 +308,7 @@ filegroups:
   - src/core/lib/iomgr/resolve_address_windows.c
   - src/core/lib/iomgr/resource_quota.c
   - src/core/lib/iomgr/sockaddr_utils.c
+  - src/core/lib/iomgr/socket_mutator.c
   - src/core/lib/iomgr/socket_utils_common_posix.c
   - src/core/lib/iomgr/socket_utils_linux.c
   - src/core/lib/iomgr/socket_utils_posix.c
diff --git a/config.m4 b/config.m4
index 988cc5b00378b9fd121382a8d5a08558b6f22557..9d1c2268c7c7d8ae5bfe73affd08fb5bd1cebf54 100644
--- a/config.m4
+++ b/config.m4
@@ -127,6 +127,7 @@ if test "$PHP_GRPC" != "no"; then
     src/core/lib/iomgr/resolve_address_windows.c \
     src/core/lib/iomgr/resource_quota.c \
     src/core/lib/iomgr/sockaddr_utils.c \
+    src/core/lib/iomgr/socket_mutator.c \
     src/core/lib/iomgr/socket_utils_common_posix.c \
     src/core/lib/iomgr/socket_utils_linux.c \
     src/core/lib/iomgr/socket_utils_posix.c \
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 8869bec32eedaa73dbc77ebed2fd4da83e807465..bba1aeab53d563a313e08e524e2d60b796e4d634 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -292,6 +292,7 @@ Pod::Spec.new do |s|
                       'src/core/lib/iomgr/sockaddr_posix.h',
                       'src/core/lib/iomgr/sockaddr_utils.h',
                       'src/core/lib/iomgr/sockaddr_windows.h',
+                      'src/core/lib/iomgr/socket_mutator.h',
                       'src/core/lib/iomgr/socket_utils.h',
                       'src/core/lib/iomgr/socket_utils_posix.h',
                       'src/core/lib/iomgr/socket_windows.h',
@@ -469,6 +470,7 @@ Pod::Spec.new do |s|
                       'src/core/lib/iomgr/resolve_address_windows.c',
                       'src/core/lib/iomgr/resource_quota.c',
                       'src/core/lib/iomgr/sockaddr_utils.c',
+                      'src/core/lib/iomgr/socket_mutator.c',
                       'src/core/lib/iomgr/socket_utils_common_posix.c',
                       'src/core/lib/iomgr/socket_utils_linux.c',
                       'src/core/lib/iomgr/socket_utils_posix.c',
@@ -695,6 +697,7 @@ Pod::Spec.new do |s|
                               'src/core/lib/iomgr/sockaddr_posix.h',
                               'src/core/lib/iomgr/sockaddr_utils.h',
                               'src/core/lib/iomgr/sockaddr_windows.h',
+                              'src/core/lib/iomgr/socket_mutator.h',
                               'src/core/lib/iomgr/socket_utils.h',
                               'src/core/lib/iomgr/socket_utils_posix.h',
                               'src/core/lib/iomgr/socket_windows.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index b071fccb827c368fbe0f5844090ff9cc436d84d0..aac12c48249dcab960e765510daa6a181a7edb43 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -212,6 +212,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/iomgr/sockaddr_posix.h )
   s.files += %w( src/core/lib/iomgr/sockaddr_utils.h )
   s.files += %w( src/core/lib/iomgr/sockaddr_windows.h )
+  s.files += %w( src/core/lib/iomgr/socket_mutator.h )
   s.files += %w( src/core/lib/iomgr/socket_utils.h )
   s.files += %w( src/core/lib/iomgr/socket_utils_posix.h )
   s.files += %w( src/core/lib/iomgr/socket_windows.h )
@@ -389,6 +390,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/iomgr/resolve_address_windows.c )
   s.files += %w( src/core/lib/iomgr/resource_quota.c )
   s.files += %w( src/core/lib/iomgr/sockaddr_utils.c )
+  s.files += %w( src/core/lib/iomgr/socket_mutator.c )
   s.files += %w( src/core/lib/iomgr/socket_utils_common_posix.c )
   s.files += %w( src/core/lib/iomgr/socket_utils_linux.c )
   s.files += %w( src/core/lib/iomgr/socket_utils_posix.c )
diff --git a/include/grpc++/support/channel_arguments.h b/include/grpc++/support/channel_arguments.h
index 49a3e9461cfc772b8eae096c37c157a5636b60ca..8d975f521487e891ccfea41eae54574af5282db8 100644
--- a/include/grpc++/support/channel_arguments.h
+++ b/include/grpc++/support/channel_arguments.h
@@ -79,6 +79,9 @@ class ChannelArguments {
   /// Set the compression algorithm for the channel.
   void SetCompressionAlgorithm(grpc_compression_algorithm algorithm);
 
+  /// Set the socket mutator for the channel.
+  void SetSocketMutator(grpc_socket_mutator* mutator);
+
   /// The given string will be sent at the front of the user agent string.
   void SetUserAgentPrefix(const grpc::string& user_agent_prefix);
 
diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h
index 1bf78e4e69c7408660114888e65d52e0df4ca3b0..8c5215faee8899668722d87e5c9ceea204de25bb 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -84,6 +84,9 @@ typedef struct grpc_server grpc_server;
     can have messages written to it and read from it. */
 typedef struct grpc_call grpc_call;
 
+/** The Socket Mutator interface allows changes on socket options */
+typedef struct grpc_socket_mutator grpc_socket_mutator;
+
 /** Type specifier for grpc_arg */
 typedef enum {
   GRPC_ARG_STRING,
@@ -215,6 +218,8 @@ typedef struct {
 /** Resolved addresses in a form used by the LB policy.
     Not intended for external use. */
 #define GRPC_ARG_LB_ADDRESSES "grpc.lb_addresses"
+/** The grpc_socket_mutator instance that set the socket options. A pointer. */
+#define GRPC_ARG_SOCKET_MUTATOR "grpc.socket_mutator"
 /** \} */
 
 /** Result of a grpc call. If the caller satisfies the prerequisites of a
diff --git a/package.xml b/package.xml
index 348ad5f23c36275de5cfae9a6a26fbf10ef1403f..1d2a443858c2635c1d079f68baaef5d0b1f4bfb2 100644
--- a/package.xml
+++ b/package.xml
@@ -219,6 +219,7 @@
     <file baseinstalldir="/" name="src/core/lib/iomgr/sockaddr_posix.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/sockaddr_utils.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/sockaddr_windows.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/socket_mutator.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/socket_utils.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/socket_utils_posix.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/socket_windows.h" role="src" />
@@ -396,6 +397,7 @@
     <file baseinstalldir="/" name="src/core/lib/iomgr/resolve_address_windows.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/resource_quota.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/sockaddr_utils.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/socket_mutator.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/socket_utils_common_posix.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/socket_utils_linux.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/socket_utils_posix.c" role="src" />
diff --git a/src/core/lib/channel/channel_args.c b/src/core/lib/channel/channel_args.c
index cfc072c0b563220b19d817efc8ea1583d58b5cce..401a2ad4fe551271e6a551fabdfbfee219ee4f67 100644
--- a/src/core/lib/channel/channel_args.c
+++ b/src/core/lib/channel/channel_args.c
@@ -298,6 +298,12 @@ uint32_t grpc_channel_args_compression_algorithm_get_states(
   }
 }
 
+grpc_channel_args *grpc_channel_args_set_socket_mutator(
+    grpc_channel_args *a, grpc_socket_mutator *mutator) {
+  grpc_arg tmp = grpc_socket_mutator_to_arg(mutator);
+  return grpc_channel_args_copy_and_add(a, &tmp, 1);
+}
+
 int grpc_channel_args_compare(const grpc_channel_args *a,
                               const grpc_channel_args *b) {
   int c = GPR_ICMP(a->num_args, b->num_args);
diff --git a/src/core/lib/channel/channel_args.h b/src/core/lib/channel/channel_args.h
index 1e05303471d6920b0bd61423da70f7dc4386229a..88fc0e37a35d76f2390f69c2740f11b3c4bea5c6 100644
--- a/src/core/lib/channel/channel_args.h
+++ b/src/core/lib/channel/channel_args.h
@@ -36,6 +36,7 @@
 
 #include <grpc/compression.h>
 #include <grpc/grpc.h>
+#include "src/core/lib/iomgr/socket_mutator.h"
 
 // Channel args are intentionally immutable, to avoid the need for locking.
 
@@ -100,6 +101,13 @@ uint32_t grpc_channel_args_compression_algorithm_get_states(
 int grpc_channel_args_compare(const grpc_channel_args *a,
                               const grpc_channel_args *b);
 
+/** Returns a channel arg instance with socket mutator added. The socket mutator
+ * will perform its mutate_fd method on all file descriptors used by the
+ * channel.
+ * If \a a is non-MULL, its args are copied. */
+grpc_channel_args *grpc_channel_args_set_socket_mutator(
+    grpc_channel_args *a, grpc_socket_mutator *mutator);
+
 /** Returns the value of argument \a name from \a args, or NULL if not found. */
 const grpc_arg *grpc_channel_args_find(const grpc_channel_args *args,
                                        const char *name);
diff --git a/src/core/lib/iomgr/socket_mutator.c b/src/core/lib/iomgr/socket_mutator.c
new file mode 100644
index 0000000000000000000000000000000000000000..8b1efb6bab0e6ff4982e9921101f25742b7bb584
--- /dev/null
+++ b/src/core/lib/iomgr/socket_mutator.c
@@ -0,0 +1,98 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/lib/iomgr/socket_mutator.h"
+
+#include <grpc/impl/codegen/grpc_types.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/useful.h>
+
+void grpc_socket_mutator_init(grpc_socket_mutator *mutator,
+                              const grpc_socket_mutator_vtable *vtable) {
+  mutator->vtable = vtable;
+  gpr_ref_init(&mutator->refcount, 1);
+}
+
+grpc_socket_mutator *grpc_socket_mutator_ref(grpc_socket_mutator *mutator) {
+  gpr_ref(&mutator->refcount);
+  return mutator;
+}
+
+bool grpc_socket_mutator_mutate_fd(grpc_socket_mutator *mutator, int fd) {
+  return mutator->vtable->mutate_fd(fd, mutator);
+}
+
+int grpc_socket_mutator_compare(grpc_socket_mutator *a,
+                                grpc_socket_mutator *b) {
+  int c = GPR_ICMP(a, b);
+  if (c != 0) {
+    grpc_socket_mutator *sma = a;
+    grpc_socket_mutator *smb = b;
+    c = GPR_ICMP(sma->vtable, smb->vtable);
+    if (c == 0) {
+      c = sma->vtable->compare(sma, smb);
+    }
+  }
+  return c;
+}
+
+void grpc_socket_mutator_unref(grpc_socket_mutator *mutator) {
+  if (gpr_unref(&mutator->refcount)) {
+    mutator->vtable->destory(mutator);
+  }
+}
+
+static void *socket_mutator_arg_copy(void *p) {
+  return grpc_socket_mutator_ref(p);
+}
+
+static void socket_mutator_arg_destroy(void *p) {
+  grpc_socket_mutator_unref(p);
+}
+
+static int socket_mutator_cmp(void *a, void *b) {
+  return grpc_socket_mutator_compare((grpc_socket_mutator *)a,
+                                     (grpc_socket_mutator *)b);
+}
+
+static const grpc_arg_pointer_vtable socket_mutator_arg_vtable = {
+    socket_mutator_arg_copy, socket_mutator_arg_destroy, socket_mutator_cmp};
+
+grpc_arg grpc_socket_mutator_to_arg(grpc_socket_mutator *mutator) {
+  grpc_arg arg;
+  arg.type = GRPC_ARG_POINTER;
+  arg.key = GRPC_ARG_SOCKET_MUTATOR;
+  arg.value.pointer.vtable = &socket_mutator_arg_vtable;
+  arg.value.pointer.p = mutator;
+  return arg;
+}
diff --git a/src/core/lib/iomgr/socket_mutator.h b/src/core/lib/iomgr/socket_mutator.h
new file mode 100644
index 0000000000000000000000000000000000000000..2f5b6c248e9db3ccc12d43029c80bf8012c1e371
--- /dev/null
+++ b/src/core/lib/iomgr/socket_mutator.h
@@ -0,0 +1,80 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_CORE_LIB_IOMGR_SOCKET_MUTATOR_H
+#define GRPC_CORE_LIB_IOMGR_SOCKET_MUTATOR_H
+
+#include <grpc/impl/codegen/grpc_types.h>
+#include <grpc/support/sync.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** The virtual table of grpc_socket_mutator */
+typedef struct {
+  /** Mutates the socket opitons of \a fd */
+  bool (*mutate_fd)(int fd, grpc_socket_mutator *mutator);
+  /** Compare socket mutator \a a and \a b */
+  int (*compare)(grpc_socket_mutator *a, grpc_socket_mutator *b);
+  /** Destroys the socket mutator instance */
+  void (*destory)(grpc_socket_mutator *mutator);
+} grpc_socket_mutator_vtable;
+
+/** The Socket Mutator interface allows changes on socket options */
+struct grpc_socket_mutator {
+  const grpc_socket_mutator_vtable *vtable;
+  gpr_refcount refcount;
+};
+
+/** called by concrete implementations to initialize the base struct */
+void grpc_socket_mutator_init(grpc_socket_mutator *mutator,
+                              const grpc_socket_mutator_vtable *vtable);
+
+/** Wrap \a mutator as a grpc_arg */
+grpc_arg grpc_socket_mutator_to_arg(grpc_socket_mutator *mutator);
+
+/** Perform the file descriptor mutation operation of \a mutator on \a fd */
+bool grpc_socket_mutator_mutate_fd(grpc_socket_mutator *mutator, int fd);
+
+/** Compare if \a a and \a b are the same mutator or have same settings */
+int grpc_socket_mutator_compare(grpc_socket_mutator *a, grpc_socket_mutator *b);
+
+grpc_socket_mutator *grpc_socket_mutator_ref(grpc_socket_mutator *mutator);
+void grpc_socket_mutator_unref(grpc_socket_mutator *mutator);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRPC_CORE_LIB_IOMGR_SOCKET_MUTATOR_H */
diff --git a/src/core/lib/iomgr/socket_utils_common_posix.c b/src/core/lib/iomgr/socket_utils_common_posix.c
index bc28bbe3166a320458e89c691faacd7ad136a78d..88e9ade253e9bef1748b7ca630f8c401948c18d6 100644
--- a/src/core/lib/iomgr/socket_utils_common_posix.c
+++ b/src/core/lib/iomgr/socket_utils_common_posix.c
@@ -209,6 +209,15 @@ grpc_error *grpc_set_socket_low_latency(int fd, int low_latency) {
   return GRPC_ERROR_NONE;
 }
 
+/* set a socket using a grpc_socket_mutator */
+grpc_error *grpc_set_socket_with_mutator(int fd, grpc_socket_mutator *mutator) {
+  GPR_ASSERT(mutator);
+  if (!grpc_socket_mutator_mutate_fd(mutator, fd)) {
+    return GRPC_ERROR_CREATE("grpc_socket_mutator failed.");
+  }
+  return GRPC_ERROR_NONE;
+}
+
 static gpr_once g_probe_ipv6_once = GPR_ONCE_INIT;
 static int g_ipv6_loopback_available;
 
diff --git a/src/core/lib/iomgr/socket_utils_posix.h b/src/core/lib/iomgr/socket_utils_posix.h
index 175fb2b71746938de57e4c5c97f37102d86a5339..e84d3781a15f9d193476806f61f568c959870def 100644
--- a/src/core/lib/iomgr/socket_utils_posix.h
+++ b/src/core/lib/iomgr/socket_utils_posix.h
@@ -39,7 +39,9 @@
 #include <sys/socket.h>
 #include <unistd.h>
 
+#include <grpc/impl/codegen/grpc_types.h>
 #include "src/core/lib/iomgr/error.h"
+#include "src/core/lib/iomgr/socket_mutator.h"
 
 /* a wrapper for accept or accept4 */
 int grpc_accept4(int sockfd, grpc_resolved_address *resolved_addr, int nonblock,
@@ -88,6 +90,9 @@ grpc_error *grpc_set_socket_sndbuf(int fd, int buffer_size_bytes);
 /* Tries to set the socket's receive buffer to given size. */
 grpc_error *grpc_set_socket_rcvbuf(int fd, int buffer_size_bytes);
 
+/* Tries to set the socket using a grpc_socket_mutator */
+grpc_error *grpc_set_socket_with_mutator(int fd, grpc_socket_mutator *mutator);
+
 /* An enum to keep track of IPv4/IPv6 socket modes.
 
    Currently, this information is only used when a socket is first created, but
diff --git a/src/core/lib/iomgr/tcp_client.h b/src/core/lib/iomgr/tcp_client.h
index 18e6e60ebcedb04cac51d0d716886f367e9aac6c..0485661316ad09b45d0c8a8a14c13cd90e047ef8 100644
--- a/src/core/lib/iomgr/tcp_client.h
+++ b/src/core/lib/iomgr/tcp_client.h
@@ -34,6 +34,7 @@
 #ifndef GRPC_CORE_LIB_IOMGR_TCP_CLIENT_H
 #define GRPC_CORE_LIB_IOMGR_TCP_CLIENT_H
 
+#include <grpc/impl/codegen/grpc_types.h>
 #include <grpc/support/time.h>
 #include "src/core/lib/iomgr/endpoint.h"
 #include "src/core/lib/iomgr/pollset_set.h"
diff --git a/src/core/lib/iomgr/tcp_client_posix.c b/src/core/lib/iomgr/tcp_client_posix.c
index bc08c94ee0041a2b6db1de08d22e86018f649d9e..13347735df96507bfe31d70b852f421bbfeb7b7a 100644
--- a/src/core/lib/iomgr/tcp_client_posix.c
+++ b/src/core/lib/iomgr/tcp_client_posix.c
@@ -51,6 +51,7 @@
 #include "src/core/lib/iomgr/ev_posix.h"
 #include "src/core/lib/iomgr/iomgr_posix.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
+#include "src/core/lib/iomgr/socket_mutator.h"
 #include "src/core/lib/iomgr/socket_utils_posix.h"
 #include "src/core/lib/iomgr/tcp_posix.h"
 #include "src/core/lib/iomgr/timer.h"
@@ -73,7 +74,8 @@ typedef struct {
   grpc_channel_args *channel_args;
 } async_connect;
 
-static grpc_error *prepare_socket(const grpc_resolved_address *addr, int fd) {
+static grpc_error *prepare_socket(const grpc_resolved_address *addr, int fd,
+                                  const grpc_channel_args *channel_args) {
   grpc_error *err = GRPC_ERROR_NONE;
 
   GPR_ASSERT(fd >= 0);
@@ -88,6 +90,16 @@ static grpc_error *prepare_socket(const grpc_resolved_address *addr, int fd) {
   }
   err = grpc_set_socket_no_sigpipe_if_possible(fd);
   if (err != GRPC_ERROR_NONE) goto error;
+  if (channel_args) {
+    for (size_t i = 0; i < channel_args->num_args; i++) {
+      if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_SOCKET_MUTATOR)) {
+        GPR_ASSERT(channel_args->args[i].type == GRPC_ARG_POINTER);
+        grpc_socket_mutator *mutator = channel_args->args[i].value.pointer.p;
+        err = grpc_set_socket_with_mutator(fd, mutator);
+        if (err != GRPC_ERROR_NONE) goto error;
+      }
+    }
+  }
   goto done;
 
 error:
@@ -287,7 +299,7 @@ static void tcp_client_connect_impl(grpc_exec_ctx *exec_ctx,
     GPR_ASSERT(grpc_sockaddr_is_v4mapped(addr, &addr4_copy));
     addr = &addr4_copy;
   }
-  if ((error = prepare_socket(addr, fd)) != GRPC_ERROR_NONE) {
+  if ((error = prepare_socket(addr, fd, channel_args)) != GRPC_ERROR_NONE) {
     grpc_exec_ctx_sched(exec_ctx, closure, error, NULL);
     return;
   }
diff --git a/src/cpp/common/channel_arguments.cc b/src/cpp/common/channel_arguments.cc
index d86ba9dd4e8c4760a80d7f299787ff3e61943830..0067d6c5e1e6708985c50c4a3d2886b478e8dbe3 100644
--- a/src/cpp/common/channel_arguments.cc
+++ b/src/cpp/common/channel_arguments.cc
@@ -39,7 +39,7 @@
 #include <grpc/impl/codegen/grpc_types.h>
 #include <grpc/support/log.h>
 #include "src/core/lib/channel/channel_args.h"
-
+#include "src/core/lib/iomgr/socket_mutator.h"
 namespace grpc {
 
 ChannelArguments::ChannelArguments() {
@@ -88,6 +88,24 @@ void ChannelArguments::SetCompressionAlgorithm(
   SetInt(GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM, algorithm);
 }
 
+void ChannelArguments::SetSocketMutator(grpc_socket_mutator* mutator) {
+  if (!mutator) {
+    return;
+  }
+  grpc_arg mutator_arg = grpc_socket_mutator_to_arg(mutator);
+  bool replaced = false;
+  for (auto it = args_.begin(); it != args_.end(); ++it) {
+    if (it->type == mutator_arg.type &&
+        grpc::string(it->key) == grpc::string(mutator_arg.key)) {
+      it->value.pointer.vtable->destroy(it->value.pointer.p);
+      it->value.pointer = mutator_arg.value.pointer;
+    }
+  }
+  if (!replaced) {
+    args_.push_back(mutator_arg);
+  }
+}
+
 // Note: a second call to this will add in front the result of the first call.
 // An example is calling this on a copy of ChannelArguments which already has a
 // prefix. The user can build up a prefix string by calling this multiple times,
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index b0041871d4c90f1a6ae713657d0967639e2c86ea..8fe36d98a31ac884e4936999c4f0faf20f9a94ae 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -121,6 +121,7 @@ CORE_SOURCE_FILES = [
   'src/core/lib/iomgr/resolve_address_windows.c',
   'src/core/lib/iomgr/resource_quota.c',
   'src/core/lib/iomgr/sockaddr_utils.c',
+  'src/core/lib/iomgr/socket_mutator.c',
   'src/core/lib/iomgr/socket_utils_common_posix.c',
   'src/core/lib/iomgr/socket_utils_linux.c',
   'src/core/lib/iomgr/socket_utils_posix.c',
diff --git a/test/core/channel/channel_args_test.c b/test/core/channel/channel_args_test.c
index 8ef1bff22e7485e9f0b7567d5fce3d89f90baa9f..d3eb969f0984030a65d33b967aaf5daba6c3d1a3 100644
--- a/test/core/channel/channel_args_test.c
+++ b/test/core/channel/channel_args_test.c
@@ -134,12 +134,26 @@ static void test_compression_algorithm_states(void) {
   grpc_channel_args_destroy(ch_args);
 }
 
+static void test_set_socket_mutator(void) {
+  grpc_channel_args *ch_args;
+  grpc_socket_mutator mutator;
+  grpc_socket_mutator_init(&mutator, NULL);
+
+  ch_args = grpc_channel_args_set_socket_mutator(NULL, &mutator);
+  GPR_ASSERT(ch_args->num_args == 1);
+  GPR_ASSERT(strcmp(ch_args->args[0].key, GRPC_ARG_SOCKET_MUTATOR) == 0);
+  GPR_ASSERT(ch_args->args[0].type == GRPC_ARG_POINTER);
+
+  grpc_channel_args_destroy(ch_args);
+}
+
 int main(int argc, char **argv) {
   grpc_test_init(argc, argv);
   grpc_init();
   test_create();
   test_set_compression_algorithm();
   test_compression_algorithm_states();
+  test_set_socket_mutator();
   grpc_shutdown();
   return 0;
 }
diff --git a/test/core/iomgr/socket_utils_test.c b/test/core/iomgr/socket_utils_test.c
index 67bc914c15ccb984647d1f9b323162a98d769722..7eee2d1d102b695ebfe50fab888a7c3f34a36e36 100644
--- a/test/core/iomgr/socket_utils_test.c
+++ b/test/core/iomgr/socket_utils_test.c
@@ -39,13 +39,57 @@
 #include "src/core/lib/iomgr/socket_utils_posix.h"
 
 #include <errno.h>
+#include <netinet/ip.h>
 #include <string.h>
 
+#include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/useful.h>
+#include "src/core/lib/iomgr/socket_mutator.h"
 #include "test/core/util/test_config.h"
 
+struct test_socket_mutator {
+  grpc_socket_mutator base;
+  int option_value;
+};
+
+static bool mutate_fd(int fd, grpc_socket_mutator *mutator) {
+  int newval;
+  socklen_t intlen = sizeof(newval);
+  struct test_socket_mutator *m = (struct test_socket_mutator *)mutator;
+
+  if (0 != setsockopt(fd, IPPROTO_IP, IP_TOS, &m->option_value,
+                      sizeof(m->option_value))) {
+    return false;
+  }
+  if (0 != getsockopt(fd, IPPROTO_IP, IP_TOS, &newval, &intlen)) {
+    return false;
+  }
+  if (newval != m->option_value) {
+    return false;
+  }
+  return true;
+}
+
+static void destroy_test_mutator(grpc_socket_mutator *mutator) {
+  struct test_socket_mutator *m = (struct test_socket_mutator *)mutator;
+  gpr_free(m);
+}
+
+static int compare_test_mutator(grpc_socket_mutator *a,
+                                grpc_socket_mutator *b) {
+  struct test_socket_mutator *ma = (struct test_socket_mutator *)a;
+  struct test_socket_mutator *mb = (struct test_socket_mutator *)b;
+  return GPR_ICMP(ma->option_value, mb->option_value);
+}
+
+static const grpc_socket_mutator_vtable mutator_vtable = {
+    mutate_fd, compare_test_mutator, destroy_test_mutator};
+
 int main(int argc, char **argv) {
   int sock;
+  grpc_error *err;
   grpc_test_init(argc, argv);
 
   sock = socket(PF_INET, SOCK_STREAM, 0);
@@ -68,6 +112,29 @@ int main(int argc, char **argv) {
   GPR_ASSERT(GRPC_LOG_IF_ERROR("set_socket_low_latency",
                                grpc_set_socket_low_latency(sock, 0)));
 
+  struct test_socket_mutator mutator;
+  grpc_socket_mutator_init(&mutator.base, &mutator_vtable);
+
+  mutator.option_value = IPTOS_LOWDELAY;
+  GPR_ASSERT(GRPC_LOG_IF_ERROR(
+      "set_socket_with_mutator",
+      grpc_set_socket_with_mutator(sock, (grpc_socket_mutator *)&mutator)));
+
+  mutator.option_value = IPTOS_THROUGHPUT;
+  GPR_ASSERT(GRPC_LOG_IF_ERROR(
+      "set_socket_with_mutator",
+      grpc_set_socket_with_mutator(sock, (grpc_socket_mutator *)&mutator)));
+
+  mutator.option_value = IPTOS_RELIABILITY;
+  GPR_ASSERT(GRPC_LOG_IF_ERROR(
+      "set_socket_with_mutator",
+      grpc_set_socket_with_mutator(sock, (grpc_socket_mutator *)&mutator)));
+
+  mutator.option_value = -1;
+  err = grpc_set_socket_with_mutator(sock, (grpc_socket_mutator *)&mutator);
+  GPR_ASSERT(err != GRPC_ERROR_NONE);
+  GRPC_ERROR_UNREF(err);
+
   close(sock);
 
   return 0;
diff --git a/test/cpp/common/channel_arguments_test.cc b/test/cpp/common/channel_arguments_test.cc
index 342f6a53396e204b6d3a5dba4f825d8ab25990d9..60d3215265f075b1a72e45a19acea901092a54f1 100644
--- a/test/cpp/common/channel_arguments_test.cc
+++ b/test/cpp/common/channel_arguments_test.cc
@@ -35,11 +35,56 @@
 
 #include <grpc++/grpc++.h>
 #include <grpc/grpc.h>
+#include <grpc/support/useful.h>
 #include <gtest/gtest.h>
+#include "src/core/lib/iomgr/socket_mutator.h"
 
 namespace grpc {
 namespace testing {
 
+namespace {
+
+// A simple grpc_socket_mutator to be used to test SetSocketMutator
+class TestSocketMutator : public grpc_socket_mutator {
+ public:
+  TestSocketMutator();
+
+  bool MutateFd(int fd) {
+    // Do nothing on the fd
+    return true;
+  }
+};
+
+//
+// C API for TestSocketMutator
+//
+
+bool test_mutator_mutate_fd(int fd, grpc_socket_mutator* mutator) {
+  TestSocketMutator* tsm = (TestSocketMutator*)mutator;
+  return tsm->MutateFd(fd);
+}
+
+int test_mutator_compare(grpc_socket_mutator* a, grpc_socket_mutator* b) {
+  return GPR_ICMP(a, b);
+}
+
+void test_mutator_destroy(grpc_socket_mutator* mutator) {
+  TestSocketMutator* tsm = (TestSocketMutator*)mutator;
+  delete tsm;
+}
+
+grpc_socket_mutator_vtable test_mutator_vtable = {
+    test_mutator_mutate_fd, test_mutator_compare, test_mutator_destroy};
+
+//
+// TestSocketMutator implementation
+//
+
+TestSocketMutator::TestSocketMutator() {
+  grpc_socket_mutator_init(this, &test_mutator_vtable);
+}
+}
+
 class ChannelArgumentsTest : public ::testing::Test {
  protected:
   ChannelArgumentsTest()
@@ -166,6 +211,26 @@ TEST_F(ChannelArgumentsTest, SetPointer) {
   EXPECT_TRUE(HasArg(arg0));
 }
 
+TEST_F(ChannelArgumentsTest, SetSocketMutator) {
+  VerifyDefaultChannelArgs();
+  grpc_arg arg0, arg1;
+  TestSocketMutator* mutator0 = new TestSocketMutator();
+  TestSocketMutator* mutator1 = new TestSocketMutator();
+  arg0 = grpc_socket_mutator_to_arg(mutator0);
+  arg1 = grpc_socket_mutator_to_arg(mutator1);
+
+  channel_args_.SetSocketMutator(mutator0);
+  EXPECT_TRUE(HasArg(arg0));
+
+  channel_args_.SetSocketMutator(mutator1);
+  EXPECT_TRUE(HasArg(arg1));
+  // arg0 is replaced by arg1
+  EXPECT_FALSE(HasArg(arg0));
+
+  // arg0 is destroyed by grpc_socket_mutator_to_arg(mutator1)
+  arg1.value.pointer.vtable->destroy(arg1.value.pointer.p);
+}
+
 TEST_F(ChannelArgumentsTest, SetUserAgentPrefix) {
   VerifyDefaultChannelArgs();
   grpc::string prefix("prefix");
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 55b8d40aca504295f0e3813921f4f61c8263df92..2acedbfc6a2fb54679bf94be460e055ada175fe5 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -835,6 +835,7 @@ src/core/lib/iomgr/sockaddr.h \
 src/core/lib/iomgr/sockaddr_posix.h \
 src/core/lib/iomgr/sockaddr_utils.h \
 src/core/lib/iomgr/sockaddr_windows.h \
+src/core/lib/iomgr/socket_mutator.h \
 src/core/lib/iomgr/socket_utils.h \
 src/core/lib/iomgr/socket_utils_posix.h \
 src/core/lib/iomgr/socket_windows.h \
@@ -1012,6 +1013,7 @@ src/core/lib/iomgr/resolve_address_uv.c \
 src/core/lib/iomgr/resolve_address_windows.c \
 src/core/lib/iomgr/resource_quota.c \
 src/core/lib/iomgr/sockaddr_utils.c \
+src/core/lib/iomgr/socket_mutator.c \
 src/core/lib/iomgr/socket_utils_common_posix.c \
 src/core/lib/iomgr/socket_utils_linux.c \
 src/core/lib/iomgr/socket_utils_posix.c \
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index 104eaa7475eba50f3d52ffe1518fa0e1ae3ba561..05c2e52a3dabfdbc355dd7779593ba8c6bc332cd 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -6695,6 +6695,7 @@
       "src/core/lib/iomgr/sockaddr_posix.h", 
       "src/core/lib/iomgr/sockaddr_utils.h", 
       "src/core/lib/iomgr/sockaddr_windows.h", 
+      "src/core/lib/iomgr/socket_mutator.h", 
       "src/core/lib/iomgr/socket_utils.h", 
       "src/core/lib/iomgr/socket_utils_posix.h", 
       "src/core/lib/iomgr/socket_windows.h", 
@@ -6852,6 +6853,8 @@
       "src/core/lib/iomgr/sockaddr_utils.c", 
       "src/core/lib/iomgr/sockaddr_utils.h", 
       "src/core/lib/iomgr/sockaddr_windows.h", 
+      "src/core/lib/iomgr/socket_mutator.c", 
+      "src/core/lib/iomgr/socket_mutator.h", 
       "src/core/lib/iomgr/socket_utils.h", 
       "src/core/lib/iomgr/socket_utils_common_posix.c", 
       "src/core/lib/iomgr/socket_utils_linux.c", 
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index c608cb89435c5ca8af6ea2a3dfed0c528180aa46..b3e5cd0267a4605af236923d5f7113b323eb899a 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -344,6 +344,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_windows.h" />
@@ -570,6 +571,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_common_posix.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_linux.c">
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index c6ca85cab6878ba55f5d7b096dfc031431954e40..2b45e4629ef71ffafa98da6e632adb7ac88dcd48 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -142,6 +142,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_common_posix.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
@@ -869,6 +872,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_windows.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils.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 764f4615b6f9b260b914c447f33845b57c3e0f89..1cb474785ae72002dd11c8031facedc26bfb3181 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
@@ -237,6 +237,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_windows.h" />
@@ -421,6 +422,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_common_posix.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_linux.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 2b720430013520183d6013adcdc0d6e1439345d5..0b3cbc2624b17fb7c88b390d166ff016d271194e 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
@@ -199,6 +199,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_common_posix.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
@@ -665,6 +668,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_windows.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils.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 ed68f03ad5b09ec1a04f5fbec4b9d4d24df5f1c9..f2d6ff9384a2b70ec97f81bde38567127636bda6 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -334,6 +334,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_windows.h" />
@@ -538,6 +539,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_common_posix.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_linux.c">
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index e8c16e531f74d773d419fa30ecb00d68d0ca1ccb..1f83cd3ce973866b03b9ba47cb1b8caa7ad06693 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -145,6 +145,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_common_posix.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
@@ -782,6 +785,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_windows.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_mutator.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>