From e5ec9ac9e2e0195e04c7c99d1c2d9a87f67404fb Mon Sep 17 00:00:00 2001
From: Yuchen Zeng <zyc@google.com>
Date: Mon, 24 Oct 2016 14:43:12 -0700
Subject: [PATCH] Add grpc_endpoint_get_socket and GRPC_SOCKET

---
 src/core/lib/iomgr/endpoint.h                 |  6 +++++
 src/core/lib/iomgr/sockaddr_posix.h           |  2 ++
 src/core/lib/iomgr/sockaddr_windows.h         |  2 ++
 src/core/lib/iomgr/tcp_posix.c                |  8 ++++++-
 .../lib/security/transport/secure_endpoint.c  |  8 ++++++-
 test/core/internal_api_canaries/iomgr.c       |  3 ++-
 test/core/util/mock_endpoint.c                | 22 ++++++++++---------
 test/core/util/passthru_endpoint.c            | 22 ++++++++++---------
 8 files changed, 50 insertions(+), 23 deletions(-)

diff --git a/src/core/lib/iomgr/endpoint.h b/src/core/lib/iomgr/endpoint.h
index 910a6f6532..22979982e4 100644
--- a/src/core/lib/iomgr/endpoint.h
+++ b/src/core/lib/iomgr/endpoint.h
@@ -39,6 +39,7 @@
 #include <grpc/support/time.h>
 #include "src/core/lib/iomgr/pollset.h"
 #include "src/core/lib/iomgr/pollset_set.h"
+#include "src/core/lib/iomgr/sockaddr.h"
 
 /* An endpoint caps a streaming channel between two communicating processes.
    Examples may be: a tcp socket, <stdin+stdout>, or some shared memory. */
@@ -59,6 +60,7 @@ struct grpc_endpoint_vtable {
   void (*shutdown)(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep);
   void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep);
   char *(*get_peer)(grpc_endpoint *ep);
+  GRPC_SOCKET *(*get_socket)(grpc_endpoint *ep);
 };
 
 /* When data is available on the connection, calls the callback with slices.
@@ -71,6 +73,10 @@ void grpc_endpoint_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
 
 char *grpc_endpoint_get_peer(grpc_endpoint *ep);
 
+/* Get the socket (file descriptor or SOCKET) used by \a ep. Return NULL if
+   \a ep is not using a socket. */
+GRPC_SOCKET *grpc_endpoint_get_socket(grpc_endpoint *ep);
+
 /* Retrieve a reference to the workqueue associated with this endpoint */
 grpc_workqueue *grpc_endpoint_get_workqueue(grpc_endpoint *ep);
 
diff --git a/src/core/lib/iomgr/sockaddr_posix.h b/src/core/lib/iomgr/sockaddr_posix.h
index b150de42f7..a4236ffaee 100644
--- a/src/core/lib/iomgr/sockaddr_posix.h
+++ b/src/core/lib/iomgr/sockaddr_posix.h
@@ -41,4 +41,6 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+typedef int GRPC_SOCKET;
+
 #endif /* GRPC_CORE_LIB_IOMGR_SOCKADDR_POSIX_H */
diff --git a/src/core/lib/iomgr/sockaddr_windows.h b/src/core/lib/iomgr/sockaddr_windows.h
index 971db5b32b..507fc71f63 100644
--- a/src/core/lib/iomgr/sockaddr_windows.h
+++ b/src/core/lib/iomgr/sockaddr_windows.h
@@ -40,4 +40,6 @@
 // must be included after the above
 #include <mswsock.h>
 
+typedef SOCKET GRPC_SOCKET;
+
 #endif /* GRPC_CORE_LIB_IOMGR_SOCKADDR_WINDOWS_H */
diff --git a/src/core/lib/iomgr/tcp_posix.c b/src/core/lib/iomgr/tcp_posix.c
index 00fd77679a..5ed00a8e98 100644
--- a/src/core/lib/iomgr/tcp_posix.c
+++ b/src/core/lib/iomgr/tcp_posix.c
@@ -464,6 +464,11 @@ static char *tcp_get_peer(grpc_endpoint *ep) {
   return gpr_strdup(tcp->peer_string);
 }
 
+static int *tcp_get_socket(grpc_endpoint *ep) {
+  grpc_tcp *tcp = (grpc_tcp *)ep;
+  return &tcp->fd;
+}
+
 static grpc_workqueue *tcp_get_workqueue(grpc_endpoint *ep) {
   grpc_tcp *tcp = (grpc_tcp *)ep;
   return grpc_fd_get_workqueue(tcp->em_fd);
@@ -476,7 +481,8 @@ static const grpc_endpoint_vtable vtable = {tcp_read,
                                             tcp_add_to_pollset_set,
                                             tcp_shutdown,
                                             tcp_destroy,
-                                            tcp_get_peer};
+                                            tcp_get_peer,
+                                            tcp_get_socket};
 
 grpc_endpoint *grpc_tcp_create(grpc_fd *em_fd, size_t slice_size,
                                const char *peer_string) {
diff --git a/src/core/lib/security/transport/secure_endpoint.c b/src/core/lib/security/transport/secure_endpoint.c
index acb0113ea8..1086c3be6a 100644
--- a/src/core/lib/security/transport/secure_endpoint.c
+++ b/src/core/lib/security/transport/secure_endpoint.c
@@ -38,6 +38,7 @@
 #include <grpc/support/slice_buffer.h>
 #include <grpc/support/sync.h>
 #include "src/core/lib/debug/trace.h"
+#include "src/core/lib/iomgr/sockaddr.h"
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/security/transport/tsi_error.h"
 #include "src/core/lib/support/string.h"
@@ -365,6 +366,10 @@ static char *endpoint_get_peer(grpc_endpoint *secure_ep) {
   return grpc_endpoint_get_peer(ep->wrapped_ep);
 }
 
+static GRPC_SOCKET *endpoint_get_socket(grpc_endpoint *secure_ep) {
+  return NULL;
+}
+
 static grpc_workqueue *endpoint_get_workqueue(grpc_endpoint *secure_ep) {
   secure_endpoint *ep = (secure_endpoint *)secure_ep;
   return grpc_endpoint_get_workqueue(ep->wrapped_ep);
@@ -377,7 +382,8 @@ static const grpc_endpoint_vtable vtable = {endpoint_read,
                                             endpoint_add_to_pollset_set,
                                             endpoint_shutdown,
                                             endpoint_destroy,
-                                            endpoint_get_peer};
+                                            endpoint_get_peer,
+                                            endpoint_get_socket};
 
 grpc_endpoint *grpc_secure_endpoint_create(
     struct tsi_frame_protector *protector, grpc_endpoint *transport,
diff --git a/test/core/internal_api_canaries/iomgr.c b/test/core/internal_api_canaries/iomgr.c
index 27d630623e..3620b93285 100644
--- a/test/core/internal_api_canaries/iomgr.c
+++ b/test/core/internal_api_canaries/iomgr.c
@@ -84,7 +84,8 @@ static void test_code(void) {
                                  grpc_endpoint_add_to_pollset_set,
                                  grpc_endpoint_shutdown,
                                  grpc_endpoint_destroy,
-                                 grpc_endpoint_get_peer};
+                                 grpc_endpoint_get_peer,
+                                 grpc_endpoint_get_socket};
   endpoint.vtable = &vtable;
 
   grpc_endpoint_read(&exec_ctx, &endpoint, NULL, NULL);
diff --git a/test/core/util/mock_endpoint.c b/test/core/util/mock_endpoint.c
index 13e0e918fb..15e88968e8 100644
--- a/test/core/util/mock_endpoint.c
+++ b/test/core/util/mock_endpoint.c
@@ -35,6 +35,7 @@
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/string_util.h>
+#include "src/core/lib/iomgr/sockaddr.h"
 
 typedef struct grpc_mock_endpoint {
   grpc_endpoint base;
@@ -95,18 +96,19 @@ static char *me_get_peer(grpc_endpoint *ep) {
   return gpr_strdup("fake:mock_endpoint");
 }
 
+static GRPC_SOCKET *me_get_socket(grpc_endpoint *ep) { return NULL; }
+
 static grpc_workqueue *me_get_workqueue(grpc_endpoint *ep) { return NULL; }
 
-static const grpc_endpoint_vtable vtable = {
-    me_read,
-    me_write,
-    me_get_workqueue,
-    me_add_to_pollset,
-    me_add_to_pollset_set,
-    me_shutdown,
-    me_destroy,
-    me_get_peer,
-};
+static const grpc_endpoint_vtable vtable = {me_read,
+                                            me_write,
+                                            me_get_workqueue,
+                                            me_add_to_pollset,
+                                            me_add_to_pollset_set,
+                                            me_shutdown,
+                                            me_destroy,
+                                            me_get_peer,
+                                            me_get_socket};
 
 grpc_endpoint *grpc_mock_endpoint_create(void (*on_write)(gpr_slice slice)) {
   grpc_mock_endpoint *m = gpr_malloc(sizeof(*m));
diff --git a/test/core/util/passthru_endpoint.c b/test/core/util/passthru_endpoint.c
index 7ed9e97bd6..5c7167207f 100644
--- a/test/core/util/passthru_endpoint.c
+++ b/test/core/util/passthru_endpoint.c
@@ -35,6 +35,7 @@
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/string_util.h>
+#include "src/core/lib/iomgr/sockaddr.h"
 
 typedef struct passthru_endpoint passthru_endpoint;
 
@@ -140,18 +141,19 @@ static char *me_get_peer(grpc_endpoint *ep) {
   return gpr_strdup("fake:mock_endpoint");
 }
 
+static GRPC_SOCKET *me_get_socket(grpc_endpoint *ep) { return NULL; }
+
 static grpc_workqueue *me_get_workqueue(grpc_endpoint *ep) { return NULL; }
 
-static const grpc_endpoint_vtable vtable = {
-    me_read,
-    me_write,
-    me_get_workqueue,
-    me_add_to_pollset,
-    me_add_to_pollset_set,
-    me_shutdown,
-    me_destroy,
-    me_get_peer,
-};
+static const grpc_endpoint_vtable vtable = {me_read,
+                                            me_write,
+                                            me_get_workqueue,
+                                            me_add_to_pollset,
+                                            me_add_to_pollset_set,
+                                            me_shutdown,
+                                            me_destroy,
+                                            me_get_peer,
+                                            me_get_socket};
 
 static void half_init(half *m, passthru_endpoint *parent) {
   m->base.vtable = &vtable;
-- 
GitLab