Merge branch 'master' into grpc_tools_docker_pregenerate_ssh_key

pull/15/head
Tim Emiola 10 years ago
commit b954c98dbf
  1. 871
      Makefile
  2. 111
      build.json
  3. 3
      include/grpc/grpc.h
  4. 2
      include/grpc/grpc_security.h
  5. 28
      src/core/iomgr/sockaddr_utils.c
  6. 6
      src/core/iomgr/sockaddr_utils.h
  7. 5
      src/core/iomgr/tcp_server.h
  8. 87
      src/core/iomgr/tcp_server_posix.c
  9. 21
      src/core/security/credentials.c
  10. 10
      src/core/security/credentials.h
  11. 80
      src/core/security/factories.c
  12. 116
      src/core/security/security_context.c
  13. 34
      src/core/security/security_context.h
  14. 24
      src/core/support/cpu_linux.c
  15. 5
      src/core/support/log_linux.c
  16. 16
      src/core/surface/server_chttp2.c
  17. 151
      src/core/tsi/fake_transport_security_test.cc
  18. 11
      src/core/tsi/ssl_transport_security.h
  19. 534
      src/core/tsi/ssl_transport_security_test.cc
  20. 17
      src/core/tsi/transport_security_interface.h
  21. 363
      src/core/tsi/transport_security_test_lib.cc
  22. 154
      src/core/tsi/transport_security_test_lib.h
  23. 2
      templates/vsprojects/vs2013/gpr_test_util.vcxproj.template
  24. 70
      test/core/end2end/dualstack_socket_test.c
  25. 1
      test/core/end2end/gen_build_json.py
  26. 47
      test/cpp/qps/client.cc
  27. 162
      test/cpp/qps/qpstest.proto
  28. 24
      test/cpp/qps/server.cc
  29. 24
      vsprojects/vs2013/build_and_run_tests.bat
  30. 82
      vsprojects/vs2013/gpr_test_util.vcxproj
  31. 6
      vsprojects/vs2013/grpc.sln
  32. 3
      vsprojects/vs2013/grpc.vcxproj
  33. 6
      vsprojects/vs2013/grpc_test_util.vcxproj
  34. 3
      vsprojects/vs2013/grpc_unsecure.vcxproj

File diff suppressed because one or more lines are too long

@ -257,6 +257,7 @@
"src/core/security/auth.c",
"src/core/security/base64.c",
"src/core/security/credentials.c",
"src/core/security/factories.c",
"src/core/security/google_root_certs.c",
"src/core/security/json_token.c",
"src/core/security/secure_endpoint.c",
@ -281,8 +282,7 @@
"src/core/tsi/fake_transport_security.h",
"src/core/tsi/ssl_transport_security.h",
"src/core/tsi/transport_security.h",
"src/core/tsi/transport_security_interface.h",
"src/core/tsi/transport_security_test_lib.h"
"src/core/tsi/transport_security_interface.h"
],
"deps": [
"gpr"
@ -301,6 +301,14 @@
"gpr"
]
},
{
"name": "gpr_test_util",
"build": "private",
"vs_project_guid": "{EAB0A629-17A9-44DB-B5FF-E91A721FE037}",
"src": [
"test/core/util/test_config.c"
]
},
{
"name": "grpc_test_util",
"build": "private",
@ -315,10 +323,9 @@
"test/core/statistics/census_log_tests.c",
"test/core/transport/transport_end2end_tests.c",
"test/core/util/grpc_profiler.c",
"test/core/util/parse_hexstring.c",
"test/core/util/port_posix.c",
"test/core/util/slice_splitter.c",
"test/core/util/test_config.c"
"test/core/util/parse_hexstring.c",
"test/core/util/slice_splitter.c"
]
},
{
@ -384,7 +391,7 @@
},
{
"name": "grpc++_test_util",
"build": "test",
"build": "private",
"src": [
"test/cpp/util/messages.proto",
"test/cpp/util/echo.proto",
@ -469,6 +476,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -479,7 +487,7 @@
"test/core/support/cancellable_test.c"
],
"deps": [
"grpc_test_util",
"gpr_test_util",
"gpr"
]
},
@ -490,7 +498,7 @@
"test/core/support/log_test.c"
],
"deps": [
"grpc_test_util",
"gpr_test_util",
"gpr"
]
},
@ -501,7 +509,7 @@
"test/core/support/useful_test.c"
],
"deps": [
"grpc_test_util",
"gpr_test_util",
"gpr"
]
},
@ -512,7 +520,7 @@
"test/core/support/cmdline_test.c"
],
"deps": [
"grpc_test_util",
"gpr_test_util",
"gpr"
]
},
@ -523,7 +531,7 @@
"test/core/support/histogram_test.c"
],
"deps": [
"grpc_test_util",
"gpr_test_util",
"gpr"
]
},
@ -534,7 +542,7 @@
"test/core/support/host_port_test.c"
],
"deps": [
"grpc_test_util",
"gpr_test_util",
"gpr"
]
},
@ -545,7 +553,7 @@
"test/core/support/slice_buffer_test.c"
],
"deps": [
"grpc_test_util",
"gpr_test_util",
"gpr"
]
},
@ -556,7 +564,7 @@
"test/core/support/slice_test.c"
],
"deps": [
"grpc_test_util",
"gpr_test_util",
"gpr"
]
},
@ -567,7 +575,7 @@
"test/core/support/string_test.c"
],
"deps": [
"grpc_test_util",
"gpr_test_util",
"gpr"
]
},
@ -578,7 +586,7 @@
"test/core/support/sync_test.c"
],
"deps": [
"grpc_test_util",
"gpr_test_util",
"gpr"
]
},
@ -589,7 +597,7 @@
"test/core/support/thd_test.c"
],
"deps": [
"grpc_test_util",
"gpr_test_util",
"gpr"
]
},
@ -600,7 +608,7 @@
"test/core/support/time_test.c"
],
"deps": [
"grpc_test_util",
"gpr_test_util",
"gpr"
]
},
@ -611,8 +619,7 @@
"test/core/support/murmur_hash_test.c"
],
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -625,6 +632,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -637,6 +645,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -649,6 +658,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -661,6 +671,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -673,6 +684,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -685,6 +697,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -697,6 +710,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -709,6 +723,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -721,6 +736,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -733,6 +749,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -745,6 +762,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -757,6 +775,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -769,6 +788,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -781,6 +801,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -793,6 +814,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -805,6 +827,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -817,6 +840,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -829,6 +853,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -841,6 +866,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -853,6 +879,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -865,6 +892,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -877,6 +905,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -889,6 +918,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -901,6 +931,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -913,6 +944,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -925,6 +957,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -937,6 +970,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -949,6 +983,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -961,6 +996,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -973,6 +1009,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -985,6 +1022,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -998,6 +1036,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1011,6 +1050,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1023,6 +1063,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1036,6 +1077,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1049,6 +1091,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1061,6 +1104,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1073,6 +1117,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1085,6 +1130,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1097,6 +1143,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1109,6 +1156,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1121,6 +1169,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1133,6 +1182,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1145,6 +1195,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1157,6 +1208,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1169,6 +1221,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1181,6 +1234,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1193,6 +1247,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1205,6 +1260,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1217,6 +1273,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1229,6 +1286,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1241,6 +1299,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1255,6 +1314,7 @@
"grpc_test_util",
"grpc++",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1269,6 +1329,7 @@
"grpc_test_util",
"grpc++",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1283,6 +1344,7 @@
"grpc_test_util",
"grpc++",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1301,6 +1363,7 @@
"grpc_test_util",
"grpc++",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1319,6 +1382,7 @@
"grpc_test_util",
"grpc++",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1338,6 +1402,7 @@
"grpc_test_util",
"grpc++",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1357,6 +1422,7 @@
"grpc_test_util",
"grpc++",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1372,6 +1438,7 @@
"grpc_test_util",
"grpc++",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1408,6 +1475,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1420,6 +1488,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1432,6 +1501,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
@ -1444,6 +1514,7 @@
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
}

@ -428,7 +428,8 @@ grpc_call_error grpc_server_request_call(grpc_server *server, void *tag_new);
grpc_server *grpc_server_create(grpc_completion_queue *cq,
const grpc_channel_args *args);
/* Add a http2 over tcp listener; returns 1 on success, 0 on failure
/* Add a http2 over tcp listener.
Returns bound port number on success, 0 on failure.
REQUIRES: server not started */
int grpc_server_add_http2_port(grpc_server *server, const char *addr);

@ -97,7 +97,6 @@ grpc_credentials *grpc_fake_transport_security_credentials_create(void);
grpc_credentials *grpc_iam_credentials_create(const char *authorization_token,
const char *authority_selector);
/* --- Secure channel creation. --- */
/* The caller of the secure_channel_create functions may override the target
@ -152,7 +151,6 @@ grpc_server_credentials *grpc_ssl_server_credentials_create(
grpc_server_credentials *grpc_fake_transport_security_server_credentials_create(
void);
/* --- Secure server creation. --- */
/* Creates a secure server using the passed-in server credentials. */

@ -153,3 +153,31 @@ int grpc_sockaddr_to_string(char **out, const struct sockaddr *addr,
errno = save_errno;
return ret;
}
int grpc_sockaddr_get_port(const struct sockaddr *addr) {
switch (addr->sa_family) {
case AF_INET:
return ntohs(((struct sockaddr_in *)addr)->sin_port);
case AF_INET6:
return ntohs(((struct sockaddr_in6 *)addr)->sin6_port);
default:
gpr_log(GPR_ERROR, "Unknown socket family %d in %s", addr->sa_family,
__FUNCTION__);
return 0;
}
}
int grpc_sockaddr_set_port(const struct sockaddr *addr, int port) {
switch (addr->sa_family) {
case AF_INET:
((struct sockaddr_in *)addr)->sin_port = htons(port);
return 1;
case AF_INET6:
((struct sockaddr_in6 *)addr)->sin6_port = htons(port);
return 1;
default:
gpr_log(GPR_ERROR, "Unknown socket family %d in %s", addr->sa_family,
__FUNCTION__);
return 0;
}
}

@ -57,6 +57,12 @@ int grpc_sockaddr_is_wildcard(const struct sockaddr *addr, int *port_out);
void grpc_sockaddr_make_wildcards(int port, struct sockaddr_in *wild4_out,
struct sockaddr_in6 *wild6_out);
/* Return the IP port number of a sockaddr */
int grpc_sockaddr_get_port(const struct sockaddr *addr);
/* Set IP port number of a sockaddr */
int grpc_sockaddr_set_port(const struct sockaddr *addr, int port);
/* Converts a sockaddr into a newly-allocated human-readable string.
Currently, only the AF_INET and AF_INET6 families are recognized.

@ -52,7 +52,8 @@ grpc_tcp_server *grpc_tcp_server_create();
void grpc_tcp_server_start(grpc_tcp_server *server, grpc_pollset *pollset,
grpc_tcp_server_cb cb, void *cb_arg);
/* Add a port to the server, returning true on success, or false otherwise.
/* Add a port to the server, returning port number on success, or negative
on failure.
The :: and 0.0.0.0 wildcard addresses are treated identically, accepting
both IPv4 and IPv6 connections, but :: is the preferred style. This usually
@ -60,6 +61,8 @@ void grpc_tcp_server_start(grpc_tcp_server *server, grpc_pollset *pollset,
but not dualstack sockets.
For raw access to the underlying sockets, see grpc_tcp_server_get_fd(). */
/* TODO(ctiller): deprecate this, and make grpc_tcp_server_add_ports to handle
all of the multiple socket port matching logic in one place */
int grpc_tcp_server_add_port(grpc_tcp_server *s, const struct sockaddr *addr,
int addr_len);

@ -154,6 +154,9 @@ static int get_max_accept_queue_size() {
/* Prepare a recently-created socket for listening. */
static int prepare_socket(int fd, const struct sockaddr *addr, int addr_len) {
struct sockaddr_storage sockname_temp;
socklen_t sockname_len;
if (fd < 0) {
goto error;
}
@ -179,13 +182,18 @@ static int prepare_socket(int fd, const struct sockaddr *addr, int addr_len) {
goto error;
}
return 1;
sockname_len = sizeof(sockname_temp);
if (getsockname(fd, (struct sockaddr *)&sockname_temp, &sockname_len) < 0) {
goto error;
}
return grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
error:
if (fd >= 0) {
close(fd);
}
return 0;
return -1;
}
/* event manager callback when reads are ready */
@ -234,39 +242,64 @@ error:
static int add_socket_to_server(grpc_tcp_server *s, int fd,
const struct sockaddr *addr, int addr_len) {
server_port *sp;
int port;
if (!prepare_socket(fd, addr, addr_len)) {
return 0;
}
gpr_mu_lock(&s->mu);
GPR_ASSERT(!s->cb && "must add ports before starting server");
/* append it to the list under a lock */
if (s->nports == s->port_capacity) {
s->port_capacity *= 2;
s->ports = gpr_realloc(s->ports, sizeof(server_port *) * s->port_capacity);
port = prepare_socket(fd, addr, addr_len);
if (port >= 0) {
gpr_mu_lock(&s->mu);
GPR_ASSERT(!s->cb && "must add ports before starting server");
/* append it to the list under a lock */
if (s->nports == s->port_capacity) {
s->port_capacity *= 2;
s->ports =
gpr_realloc(s->ports, sizeof(server_port *) * s->port_capacity);
}
sp = &s->ports[s->nports++];
sp->server = s;
sp->fd = fd;
sp->emfd = grpc_fd_create(fd);
GPR_ASSERT(sp->emfd);
gpr_mu_unlock(&s->mu);
}
sp = &s->ports[s->nports++];
sp->server = s;
sp->fd = fd;
sp->emfd = grpc_fd_create(fd);
GPR_ASSERT(sp->emfd);
gpr_mu_unlock(&s->mu);
return 1;
return port;
}
int grpc_tcp_server_add_port(grpc_tcp_server *s, const struct sockaddr *addr,
int addr_len) {
int ok = 0;
int allocated_port1 = -1;
int allocated_port2 = -1;
int i;
int fd;
grpc_dualstack_mode dsmode;
struct sockaddr_in6 addr6_v4mapped;
struct sockaddr_in wild4;
struct sockaddr_in6 wild6;
struct sockaddr_in addr4_copy;
struct sockaddr *allocated_addr = NULL;
struct sockaddr_storage sockname_temp;
socklen_t sockname_len;
int port;
/* Check if this is a wildcard port, and if so, try to keep the port the same
as some previously created listener. */
if (grpc_sockaddr_get_port(addr) == 0) {
for (i = 0; i < s->nports; i++) {
sockname_len = sizeof(sockname_temp);
if (0 == getsockname(s->ports[i].fd, (struct sockaddr *)&sockname_temp,
&sockname_len)) {
port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
if (port > 0) {
allocated_addr = malloc(addr_len);
memcpy(allocated_addr, addr, addr_len);
grpc_sockaddr_set_port(allocated_addr, port);
addr = allocated_addr;
break;
}
}
}
}
if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) {
addr = (const struct sockaddr *)&addr6_v4mapped;
addr_len = sizeof(addr6_v4mapped);
@ -280,12 +313,15 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const struct sockaddr *addr,
addr = (struct sockaddr *)&wild6;
addr_len = sizeof(wild6);
fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode);
ok |= add_socket_to_server(s, fd, addr, addr_len);
allocated_port1 = add_socket_to_server(s, fd, addr, addr_len);
if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
return ok;
goto done;
}
/* If we didn't get a dualstack socket, also listen on 0.0.0.0. */
if (port == 0 && allocated_port1 > 0) {
grpc_sockaddr_set_port((struct sockaddr *)&wild4, allocated_port1);
}
addr = (struct sockaddr *)&wild4;
addr_len = sizeof(wild4);
}
@ -299,8 +335,11 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const struct sockaddr *addr,
addr = (struct sockaddr *)&addr4_copy;
addr_len = sizeof(addr4_copy);
}
ok |= add_socket_to_server(s, fd, addr, addr_len);
return ok;
allocated_port2 = add_socket_to_server(s, fd, addr, addr_len);
done:
gpr_free(allocated_addr);
return allocated_port1 >= 0 ? allocated_port1 : allocated_port2;
}
int grpc_tcp_server_get_fd(grpc_tcp_server *s, int index) {

@ -819,6 +819,26 @@ const grpc_credentials_array *grpc_composite_credentials_get_credentials(
return &c->inner;
}
grpc_credentials *grpc_credentials_contains_type(
grpc_credentials *creds, const char *type,
grpc_credentials **composite_creds) {
size_t i;
if (!strcmp(creds->type, type)) {
if (composite_creds != NULL) *composite_creds = NULL;
return creds;
} else if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE)) {
const grpc_credentials_array *inner_creds_array =
grpc_composite_credentials_get_credentials(creds);
for (i = 0; i < inner_creds_array->num_creds; i++) {
if (!strcmp(type, inner_creds_array->creds_array[i]->type)) {
if (composite_creds != NULL) *composite_creds = creds;
return inner_creds_array->creds_array[i];
}
}
}
return NULL;
}
/* -- IAM credentials. -- */
typedef struct {
@ -877,4 +897,3 @@ grpc_credentials *grpc_iam_credentials_create(const char *token,
/* -- Default credentials TODO(jboeuf). -- */
grpc_credentials *grpc_default_credentials_create(void) { return NULL; }

@ -108,6 +108,14 @@ typedef struct {
const grpc_credentials_array *grpc_composite_credentials_get_credentials(
grpc_credentials *composite_creds);
/* Returns creds if creds is of the specified type or the inner creds of the
specified type (if found), if the creds is of type COMPOSITE.
If composite_creds is not NULL, *composite_creds will point to creds if of
type COMPOSITE in case of success. */
grpc_credentials *grpc_credentials_contains_type(
grpc_credentials *creds, const char *type,
grpc_credentials **composite_creds);
/* Exposed for testing only. */
grpc_credentials_status
grpc_oauth2_token_fetcher_credentials_parse_server_response(
@ -118,7 +126,6 @@ grpc_oauth2_token_fetcher_credentials_parse_server_response(
grpc_credentials *grpc_fake_oauth2_credentials_create(
const char *token_md_value, int is_async);
/* --- grpc_server_credentials. --- */
typedef struct {
@ -136,5 +143,4 @@ struct grpc_server_credentials {
const grpc_ssl_config *grpc_ssl_server_credentials_get_config(
const grpc_server_credentials *ssl_creds);
#endif /* __GRPC_INTERNAL_SECURITY_CREDENTIALS_H__ */

@ -0,0 +1,80 @@
/*
*
* Copyright 2014, 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 <string.h>
#include "src/core/security/credentials.h"
#include "src/core/security/security_context.h"
#include "src/core/surface/lame_client.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/useful.h>
grpc_channel *grpc_secure_channel_create(grpc_credentials *creds,
const char *target,
const grpc_channel_args *args) {
grpc_secure_channel_factory factories[] = {
{GRPC_CREDENTIALS_TYPE_SSL, grpc_ssl_channel_create},
{GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY,
grpc_fake_transport_security_channel_create}};
return grpc_secure_channel_create_with_factories(
factories, GPR_ARRAY_SIZE(factories), creds, target, args);
}
grpc_server *grpc_secure_server_create(grpc_server_credentials *creds,
grpc_completion_queue *cq,
const grpc_channel_args *args) {
grpc_security_status status = GRPC_SECURITY_ERROR;
grpc_security_context *ctx = NULL;
grpc_server *server = NULL;
if (creds == NULL) return NULL; /* TODO(ctiller): Return lame server. */
if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL)) {
status = grpc_ssl_server_security_context_create(
grpc_ssl_server_credentials_get_config(creds), &ctx);
} else if (!strcmp(creds->type,
GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY)) {
ctx = grpc_fake_server_security_context_create();
status = GRPC_SECURITY_OK;
}
if (status != GRPC_SECURITY_OK) {
gpr_log(GPR_ERROR,
"Unable to create secure server with credentials of type %s.",
creds->type);
return NULL; /* TODO(ctiller): Return lame server. */
}
server = grpc_secure_server_create_internal(cq, args, ctx);
grpc_security_context_unref(ctx);
return server;
}

@ -438,19 +438,18 @@ error:
return GRPC_SECURITY_ERROR;
}
/* -- High level objects. -- */
static grpc_channel *grpc_ssl_channel_create(grpc_credentials *creds,
const grpc_ssl_config *config,
const char *target,
const grpc_channel_args *args) {
grpc_channel *grpc_ssl_channel_create(grpc_credentials *ssl_creds,
grpc_credentials *request_metadata_creds,
const char *target,
const grpc_channel_args *args) {
grpc_channel_security_context *ctx = NULL;
grpc_channel *channel = NULL;
grpc_security_status status = GRPC_SECURITY_OK;
size_t i = 0;
const char *secure_peer_name = target;
for (i = 0; args && i < args->num_args; i++) {
grpc_arg *arg = &args->args[i];
if (!strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) &&
@ -459,8 +458,9 @@ static grpc_channel *grpc_ssl_channel_create(grpc_credentials *creds,
break;
}
}
status = grpc_ssl_channel_security_context_create(creds, config,
secure_peer_name, &ctx);
status = grpc_ssl_channel_security_context_create(
request_metadata_creds, grpc_ssl_credentials_get_config(ssl_creds),
secure_peer_name, &ctx);
if (status != GRPC_SECURITY_OK) {
return grpc_lame_client_channel_create();
}
@ -469,36 +469,22 @@ static grpc_channel *grpc_ssl_channel_create(grpc_credentials *creds,
return channel;
}
static grpc_credentials *get_creds_from_composite(
grpc_credentials *composite_creds, const char *type) {
size_t i;
const grpc_credentials_array *inner_creds_array =
grpc_composite_credentials_get_credentials(composite_creds);
for (i = 0; i < inner_creds_array->num_creds; i++) {
if (!strcmp(type, inner_creds_array->creds_array[i]->type)) {
return inner_creds_array->creds_array[i];
}
}
return NULL;
grpc_channel *grpc_fake_transport_security_channel_create(
grpc_credentials *fake_creds, grpc_credentials *request_metadata_creds,
const char *target, const grpc_channel_args *args) {
grpc_channel_security_context *ctx =
grpc_fake_channel_security_context_create(request_metadata_creds);
grpc_channel *channel =
grpc_secure_channel_create_internal(target, args, ctx);
grpc_security_context_unref(&ctx->base);
return channel;
}
static grpc_channel *grpc_channel_create_from_composite_creds(
grpc_credentials *composite_creds, const char *target,
grpc_channel *grpc_secure_channel_create_with_factories(
const grpc_secure_channel_factory *factories, size_t num_factories,
grpc_credentials *creds, const char *target,
const grpc_channel_args *args) {
grpc_credentials *creds =
get_creds_from_composite(composite_creds, GRPC_CREDENTIALS_TYPE_SSL);
if (creds != NULL) {
return grpc_ssl_channel_create(
composite_creds, grpc_ssl_credentials_get_config(creds), target, args);
}
gpr_log(GPR_ERROR, "Credentials is insufficient to create a secure channel.");
return grpc_lame_client_channel_create();
}
grpc_channel *grpc_secure_channel_create(grpc_credentials *creds,
const char *target,
const grpc_channel_args *args) {
size_t i;
if (creds == NULL) {
gpr_log(GPR_ERROR, "No credentials to create a secure channel.");
return grpc_lame_client_channel_create();
@ -508,25 +494,22 @@ grpc_channel *grpc_secure_channel_create(grpc_credentials *creds,
"Credentials is insufficient to create a secure channel.");
return grpc_lame_client_channel_create();
}
if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL)) {
return grpc_ssl_channel_create(NULL, grpc_ssl_credentials_get_config(creds),
target, args);
} else if (!strcmp(creds->type,
GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY)) {
grpc_channel_security_context *ctx =
grpc_fake_channel_security_context_create(NULL);
grpc_channel *channel =
grpc_secure_channel_create_internal(target, args, ctx);
grpc_security_context_unref(&ctx->base);
return channel;
} else if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE)) {
return grpc_channel_create_from_composite_creds(creds, target, args);
} else {
gpr_log(GPR_ERROR,
"Unknown credentials type %s for creating a secure channel.",
creds->type);
return grpc_lame_client_channel_create();
for (i = 0; i < num_factories; i++) {
grpc_credentials *composite_creds = NULL;
grpc_credentials *transport_security_creds = NULL;
transport_security_creds = grpc_credentials_contains_type(
creds, factories[i].creds_type, &composite_creds);
if (transport_security_creds != NULL) {
return factories[i].factory(transport_security_creds, composite_creds,
target, args);
}
}
gpr_log(GPR_ERROR,
"Unknown credentials type %s for creating a secure channel.",
creds->type);
return grpc_lame_client_channel_create();
}
grpc_channel *grpc_default_secure_channel_create(
@ -534,30 +517,3 @@ grpc_channel *grpc_default_secure_channel_create(
return grpc_secure_channel_create(grpc_default_credentials_create(), target,
args);
}
grpc_server *grpc_secure_server_create(grpc_server_credentials *creds,
grpc_completion_queue *cq,
const grpc_channel_args *args) {
grpc_security_status status = GRPC_SECURITY_ERROR;
grpc_security_context *ctx = NULL;
grpc_server *server = NULL;
if (creds == NULL) return NULL; /* TODO(ctiller): Return lame server. */
if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL)) {
status = grpc_ssl_server_security_context_create(
grpc_ssl_server_credentials_get_config(creds), &ctx);
} else if (!strcmp(creds->type,
GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY)) {
ctx = grpc_fake_server_security_context_create();
status = GRPC_SECURITY_OK;
} else {
gpr_log(GPR_ERROR,
"Unable to create secure server with credentials of type %s.",
creds->type);
}
if (status != GRPC_SECURITY_OK) {
return NULL; /* TODO(ctiller): Return lame server. */
}
server = grpc_secure_server_create_internal(cq, args, ctx);
grpc_security_context_unref(ctx);
return server;
}

@ -159,17 +159,41 @@ grpc_security_status grpc_ssl_channel_security_context_create(
grpc_security_status grpc_ssl_server_security_context_create(
const grpc_ssl_config *config, grpc_security_context **ctx);
/* --- Creation of high level objects. --- */
/* Secure client channel creation. */
grpc_channel *grpc_ssl_channel_create(grpc_credentials *ssl_creds,
grpc_credentials *request_metadata_creds,
const char *target,
const grpc_channel_args *args);
grpc_channel *grpc_fake_transport_security_channel_create(
grpc_credentials *fake_creds, grpc_credentials *request_metadata_creds,
const char *target, const grpc_channel_args *args);
grpc_channel *grpc_secure_channel_create_internal(
const char *target, const grpc_channel_args *args,
grpc_channel_security_context *ctx);
typedef grpc_channel *(*grpc_secure_channel_factory_func)(
grpc_credentials *transport_security_creds,
grpc_credentials *request_metadata_creds, const char *target,
const grpc_channel_args *args);
typedef struct {
const char *creds_type;
grpc_secure_channel_factory_func factory;
} grpc_secure_channel_factory;
grpc_channel *grpc_secure_channel_create_with_factories(
const grpc_secure_channel_factory *factories, size_t num_factories,
grpc_credentials *creds, const char *target, const grpc_channel_args *args);
/* Secure server creation. */
grpc_server *grpc_secure_server_create_internal(
grpc_completion_queue *cq, const grpc_channel_args *args,
grpc_security_context *ctx);
#endif /* __GRPC_INTERNAL_SECURITY_SECURITY_CONTEXT_H__ */
grpc_server *grpc_secure_server_create_internal(grpc_completion_queue *cq,
const grpc_channel_args *args,
grpc_security_context *ctx);
#endif /* __GRPC_INTERNAL_SECURITY_SECURITY_CONTEXT_H__ */

@ -37,13 +37,37 @@
#include "src/core/support/cpu.h"
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#define GRPC_GNU_SOURCE
#endif
#ifndef __USE_GNU
#define __USE_GNU
#define GRPC_USE_GNU
#endif
#ifndef __USE_MISC
#define __USE_MISC
#define GRPC_USE_MISC
#endif
#include <sched.h>
#ifdef GRPC_GNU_SOURCE
#undef _GNU_SOURCE
#undef GRPC_GNU_SOURCE
#endif
#ifdef GRPC_USE_GNU
#undef __USE_GNU
#undef GRPC_USE_GNU
#endif
#ifdef GRPC_USE_MISC
#undef __USE_MISC
#undef GRPC_USE_MISC
#endif
#include <errno.h>
#include <unistd.h>

@ -54,7 +54,10 @@ void gpr_log(const char *file, int line, gpr_log_severity severity,
char *message = NULL;
va_list args;
va_start(args, format);
vasprintf(&message, format, args);
if (vasprintf(&message, format, args) == -1) {
va_end(args);
return;
}
va_end(args);
gpr_log_message(file, line, severity, message);
free(message);

@ -76,6 +76,8 @@ int grpc_server_add_http2_port(grpc_server *server, const char *addr) {
grpc_tcp_server *tcp = NULL;
size_t i;
int count = 0;
int port_num = -1;
int port_temp;
resolved = grpc_blocking_resolve_address(addr, "http");
if (!resolved) {
@ -88,9 +90,15 @@ int grpc_server_add_http2_port(grpc_server *server, const char *addr) {
}
for (i = 0; i < resolved->naddrs; i++) {
if (grpc_tcp_server_add_port(tcp,
(struct sockaddr *)&resolved->addrs[i].addr,
resolved->addrs[i].len)) {
port_temp = grpc_tcp_server_add_port(
tcp, (struct sockaddr *)&resolved->addrs[i].addr,
resolved->addrs[i].len);
if (port_temp >= 0) {
if (port_num == -1) {
port_num = port_temp;
} else {
GPR_ASSERT(port_num == port_temp);
}
count++;
}
}
@ -108,7 +116,7 @@ int grpc_server_add_http2_port(grpc_server *server, const char *addr) {
/* Register with the server only upon success */
grpc_server_add_listener(server, tcp, start, destroy);
return 1;
return port_num;
/* Error path: cleanup and return */
error:

@ -1,151 +0,0 @@
/*
*
* Copyright 2014, 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/tsi/fake_transport_security.h"
#include "src/core/tsi/transport_security_test_lib.h"
#include <gtest/gtest.h>
#include "util/random/permute-inl.h"
namespace {
void CheckStringPeerProperty(const tsi_peer& peer, int property_index,
const char* expected_name,
const char* expected_value) {
EXPECT_LT(property_index, peer.property_count);
const tsi_peer_property* property = &peer.properties[property_index];
EXPECT_EQ(TSI_PEER_PROPERTY_TYPE_STRING, property->type);
EXPECT_EQ(string(expected_name), string(property->name));
EXPECT_EQ(string(expected_value),
string(property->value.string.data, property->value.string.length));
}
class FakeTransportSecurityTest : public tsi::test::TransportSecurityTest {
protected:
void SetupHandshakers() override {
client_handshaker_.reset(tsi_create_fake_handshaker(1));
server_handshaker_.reset(tsi_create_fake_handshaker(0));
}
void CheckPeer(tsi_handshaker* handshaker) {
tsi_peer peer;
EXPECT_EQ(TSI_OK, tsi_handshaker_extract_peer(handshaker, &peer));
EXPECT_EQ(1, peer.property_count);
CheckStringPeerProperty(peer, 0, TSI_CERTIFICATE_TYPE_PEER_PROPERTY,
TSI_FAKE_CERTIFICATE_TYPE);
tsi_peer_destruct(&peer);
}
void CheckHandshakeResults() override {
CheckPeer(client_handshaker_.get());
CheckPeer(server_handshaker_.get());
}
const tsi::test::TestConfig* config() {
return &config_;
}
tsi::test::TestConfig config_;
};
TEST_F(FakeTransportSecurityTest, Handshake) {
PerformHandshake();
}
TEST_F(FakeTransportSecurityTest, HandshakeSmallBuffer) {
config_.handshake_buffer_size = 3;
PerformHandshake();
}
TEST_F(FakeTransportSecurityTest, PingPong) {
PingPong();
}
TEST_F(FakeTransportSecurityTest, RoundTrip) {
config_.client_message = big_message_;
config_.server_message = small_message_;
DoRoundTrip();
}
TEST_F(FakeTransportSecurityTest, RoundTripSmallMessageBuffer) {
config_.message_buffer_allocated_size = 42;
config_.client_message = big_message_;
config_.server_message = small_message_;
DoRoundTrip();
}
TEST_F(FakeTransportSecurityTest, RoundTripSmallProtectedBufferSize) {
config_.protected_buffer_size = 37;
config_.client_message = big_message_;
config_.server_message = small_message_;
DoRoundTrip();
}
TEST_F(FakeTransportSecurityTest, RoundTripSmallReadBufferSize) {
config_.read_buffer_allocated_size = 41;
config_.client_message = big_message_;
config_.server_message = small_message_;
DoRoundTrip();
}
TEST_F(FakeTransportSecurityTest, RoundTripSmallClientFrames) {
config_.set_client_max_output_protected_frame_size(39);
config_.client_message = big_message_;
config_.server_message = small_message_;
DoRoundTrip();
}
TEST_F(FakeTransportSecurityTest, RoundTripSmallServerFrames) {
config_.set_server_max_output_protected_frame_size(43);
config_.client_message = small_message_;
config_.server_message = big_message_;
DoRoundTrip();
}
TEST_F(FakeTransportSecurityTest, RoundTripOddBufferSizes) {
int odd_sizes[] = {33, 67, 135, 271, 523};
RandomPermutation<int> permute(odd_sizes, arraysize(odd_sizes),
random_.get());
permute.Permute();
LOG(ERROR) << odd_sizes[0] << "\t" << odd_sizes[1] << "\t" << odd_sizes[2]
<< "\t" << odd_sizes[3] << "\t" << odd_sizes[4];
config_.message_buffer_allocated_size = odd_sizes[0];
config_.protected_buffer_size = odd_sizes[1];
config_.read_buffer_allocated_size = odd_sizes[2];
config_.set_client_max_output_protected_frame_size(odd_sizes[3]);
config_.set_server_max_output_protected_frame_size(odd_sizes[4]);
config_.client_message = big_message_;
config_.server_message = small_message_;
DoRoundTrip();
}
} // namespace

@ -43,6 +43,17 @@ extern "C" {
/* Value for the TSI_CERTIFICATE_TYPE_PEER_PROPERTY property for X509 certs. */
#define TSI_X509_CERTIFICATE_TYPE "X509"
/* This property is of type TSI_PEER_PROPERTY_STRING. */
#define TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY "x509_subject_common_name"
/* This property is of type TSI_PEER_PROPERTY_LIST and the children contain
unnamed (name == NULL) properties of type TSI_PEER_PROPERTY_STRING. */
#define TSI_X509_SUBJECT_ALTERNATIVE_NAMES_PEER_PROPERTY \
"x509_subject_alternative_names"
/* This property is of type TSI_PEER_PROPERTY_STRING. */
#define TSI_SSL_ALPN_SELECTED_PROTOCOL "ssl_alpn_selected_protocol"
/* --- tsi_ssl_handshaker_factory object ---
This object creates tsi_handshaker objects implemented in terms of the

@ -1,534 +0,0 @@
/*
*
* Copyright 2014, 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 <memory>
#include "base/commandlineflags.h"
#include "file/base/helpers.h"
#include "file/base/options.pb.h"
#include "file/base/path.h"
#include "src/core/tsi/transport_security_test_lib.h"
#include "src/core/tsi/ssl_transport_security.h"
#include "util/random/permute-inl.h"
namespace {
const char kTestCredsDir[] =
"/internal/tsi/test_creds/";
enum AlpnMode {
NO_ALPN,
ALPN_CLIENT_NO_SERVER,
ALPN_SERVER_NO_CLIENT,
ALPN_CLIENT_SERVER_OK,
ALPN_CLIENT_SERVER_MISMATCH
};
class SslTestConfig : public tsi::test::TestConfig {
public:
SslTestConfig()
: do_client_authentication(false),
subject_name_indication(nullptr),
use_bad_client_cert(false),
use_bad_server_cert(false),
alpn_mode(NO_ALPN) {}
bool do_client_authentication;
const char* subject_name_indication;
bool use_bad_client_cert;
bool use_bad_server_cert;
AlpnMode alpn_mode;
};
struct TsiSslHandshakerFactoryDeleter {
inline void operator()(tsi_ssl_handshaker_factory* ptr) {
tsi_ssl_handshaker_factory_destroy(ptr);
}
};
typedef std::unique_ptr<tsi_ssl_handshaker_factory,
TsiSslHandshakerFactoryDeleter>
TsiSslHandshakerFactoryUniquePtr;
class SslTransportSecurityTest : public tsi::test::TransportSecurityTest {
protected:
void CheckSubjectAltName(const tsi_peer_property& property,
const string& expected_subject_alt_name) {
EXPECT_EQ(property.type, TSI_PEER_PROPERTY_TYPE_STRING);
EXPECT_EQ(property.name, nullptr);
EXPECT_EQ(
string(property.value.string.data, property.value.string.length),
expected_subject_alt_name);
}
const tsi_peer_property* CheckBasicAuthenticatedPeerAndGetCommonName(
const tsi_peer* peer) {
const tsi_peer_property* property =
tsi_peer_get_property_by_name(peer, TSI_CERTIFICATE_TYPE_PEER_PROPERTY);
EXPECT_NE(property, nullptr);
EXPECT_EQ(property->type, TSI_PEER_PROPERTY_TYPE_STRING);
EXPECT_EQ(
string(property->value.string.data, property->value.string.length),
string(TSI_X509_CERTIFICATE_TYPE));
property = tsi_peer_get_property_by_name(
peer, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY);
EXPECT_EQ(property->type, TSI_PEER_PROPERTY_TYPE_STRING);
return property;
}
void CheckServer0Peer(tsi_peer* peer) {
const tsi_peer_property* property =
CheckBasicAuthenticatedPeerAndGetCommonName(peer);
EXPECT_EQ(
string(property->value.string.data, property->value.string.length),
string("*.test.google.com.au"));
property = tsi_peer_get_property_by_name(
peer, TSI_X509_SUBJECT_ALTERNATIVE_NAMES_PEER_PROPERTY);
EXPECT_EQ(property->type, TSI_PEER_PROPERTY_TYPE_LIST);
EXPECT_EQ(property->value.list.child_count, 0);
EXPECT_EQ(1, tsi_ssl_peer_matches_name(peer, "foo.test.google.com.au"));
EXPECT_EQ(1, tsi_ssl_peer_matches_name(peer, "bar.test.google.com.au"));
EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "bar.test.google.blah"));
EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "foo.bar.test.google.com.au"));
EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "test.google.com.au"));
tsi_peer_destruct(peer);
}
void CheckServer1Peer(tsi_peer* peer) {
const tsi_peer_property* property =
CheckBasicAuthenticatedPeerAndGetCommonName(peer);
EXPECT_EQ(
string(property->value.string.data, property->value.string.length),
string("*.test.google.com"));
property = tsi_peer_get_property_by_name(
peer, TSI_X509_SUBJECT_ALTERNATIVE_NAMES_PEER_PROPERTY);
EXPECT_EQ(property->type, TSI_PEER_PROPERTY_TYPE_LIST);
EXPECT_EQ(property->value.list.child_count, 3);
CheckSubjectAltName(property->value.list.children[0], "*.test.google.fr");
CheckSubjectAltName(property->value.list.children[1],
"waterzooi.test.google.be");
CheckSubjectAltName(property->value.list.children[2], "*.test.youtube.com");
EXPECT_EQ(1, tsi_ssl_peer_matches_name(peer, "foo.test.google.com"));
EXPECT_EQ(1, tsi_ssl_peer_matches_name(peer, "bar.test.google.fr"));
EXPECT_EQ(1, tsi_ssl_peer_matches_name(peer, "waterzooi.test.google.be"));
EXPECT_EQ(1, tsi_ssl_peer_matches_name(peer, "foo.test.youtube.com"));
EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "bar.foo.test.google.com"));
EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "test.google.fr"));
EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "tartines.test.google.be"));
EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "tartines.youtube.com"));
tsi_peer_destruct(peer);
}
void CheckClientPeer(tsi_peer* peer, bool is_authenticated) {
if (!is_authenticated) {
EXPECT_EQ(peer->property_count,
config_.alpn_mode == ALPN_CLIENT_SERVER_OK ? 1 : 0);
} else {
const tsi_peer_property* property =
CheckBasicAuthenticatedPeerAndGetCommonName(peer);
EXPECT_EQ(
string(property->value.string.data, property->value.string.length),
string("testclient"));
}
tsi_peer_destruct(peer);
}
void SetupHandshakers() override {
tsi_ssl_handshaker_factory* client_handshaker_factory;
const unsigned char* client_cert = NULL;
unsigned int client_cert_size = 0;
const unsigned char* client_key = NULL;
unsigned int client_key_size = 0;
if (config_.do_client_authentication) {
if (config_.use_bad_client_cert) {
client_cert =
reinterpret_cast<const unsigned char*>(badclient_cert_.data());
client_cert_size = badclient_cert_.size();
client_key =
reinterpret_cast<const unsigned char*>(badclient_key_.data());
client_key_size = badclient_key_.size();
} else {
client_cert =
reinterpret_cast<const unsigned char*>(client_cert_.data());
client_cert_size = client_cert_.size();
client_key = reinterpret_cast<const unsigned char*>(client_key_.data());
client_key_size = client_key_.size();
}
}
const unsigned char** client_alpn_protocols(nullptr);
const unsigned char* client_alpn_protocols_lengths(nullptr);
uint16_t num_client_alpn_protocols = 0;
if (config_.alpn_mode == ALPN_CLIENT_NO_SERVER ||
config_.alpn_mode == ALPN_CLIENT_SERVER_OK ||
config_.alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) {
client_alpn_protocols =
reinterpret_cast<const unsigned char**>(&client_alpn_protocols_[0]);
client_alpn_protocols_lengths = &client_alpn_protocols_lengths_[0];
num_client_alpn_protocols = client_alpn_protocols_.size();
}
EXPECT_EQ(tsi_create_ssl_client_handshaker_factory(
client_key, client_key_size, client_cert, client_cert_size,
reinterpret_cast<const unsigned char*>(root_certs_.data()),
root_certs_.size(), NULL, client_alpn_protocols,
client_alpn_protocols_lengths, num_client_alpn_protocols,
&client_handshaker_factory),
TSI_OK);
client_handshaker_factory_.reset(client_handshaker_factory);
const unsigned char** server_alpn_protocols(nullptr);
const unsigned char* server_alpn_protocols_lengths(nullptr);
uint16_t num_server_alpn_protocols = 0;
if (config_.alpn_mode == ALPN_SERVER_NO_CLIENT ||
config_.alpn_mode == ALPN_CLIENT_SERVER_OK ||
config_.alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) {
server_alpn_protocols =
reinterpret_cast<const unsigned char**>(&server_alpn_protocols_[0]);
server_alpn_protocols_lengths = &server_alpn_protocols_lengths_[0];
num_server_alpn_protocols = server_alpn_protocols_.size();
if (config_.alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) {
// Remove the last element that is common.
num_server_alpn_protocols--;
}
}
tsi_ssl_handshaker_factory* server_handshaker_factory;
EXPECT_EQ(
tsi_create_ssl_server_handshaker_factory(
config_.use_bad_server_cert ? &badserver_keys_[0]
: &server_keys_[0],
config_.use_bad_server_cert ? &badserver_keys_sizes_[0]
: &server_keys_sizes_[0],
config_.use_bad_server_cert ? &badserver_certs_[0]
: &server_certs_[0],
config_.use_bad_server_cert ? &badserver_certs_sizes_[0]
: &server_certs_sizes_[0],
config_.use_bad_server_cert ? badserver_keys_.size()
: server_keys_.size(),
config_.do_client_authentication
? reinterpret_cast<const unsigned char*>(root_certs_.data())
: NULL,
config_.do_client_authentication ? root_certs_.size() : 0, NULL,
server_alpn_protocols, server_alpn_protocols_lengths,
num_server_alpn_protocols, &server_handshaker_factory),
TSI_OK);
server_handshaker_factory_.reset(server_handshaker_factory);
tsi_handshaker* client_handshaker;
EXPECT_EQ(tsi_ssl_handshaker_factory_create_handshaker(
client_handshaker_factory, config_.subject_name_indication,
&client_handshaker),
TSI_OK);
client_handshaker_.reset(client_handshaker);
tsi_handshaker* server_handshaker;
EXPECT_EQ(tsi_ssl_handshaker_factory_create_handshaker(
server_handshaker_factory, NULL, &server_handshaker),
TSI_OK);
server_handshaker_.reset(server_handshaker);
}
void CheckAlpn(const tsi_peer* peer) {
const tsi_peer_property* alpn_property =
tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL);
if (config_.alpn_mode != ALPN_CLIENT_SERVER_OK) {
EXPECT_EQ(nullptr, alpn_property);
} else {
EXPECT_NE(nullptr, alpn_property);
EXPECT_EQ(TSI_PEER_PROPERTY_TYPE_STRING, alpn_property->type);
string expected_match("baz");
EXPECT_EQ(expected_match, string(alpn_property->value.string.data,
alpn_property->value.string.length));
}
}
void CheckHandshakeResults() override {
tsi_peer peer;
bool expect_success =
!(config_.use_bad_server_cert ||
(config_.use_bad_client_cert && config_.do_client_authentication));
tsi_result result = tsi_handshaker_get_result(client_handshaker_.get());
EXPECT_NE(result, TSI_HANDSHAKE_IN_PROGRESS);
if (expect_success) {
EXPECT_EQ(result, TSI_OK);
EXPECT_EQ(tsi_handshaker_extract_peer(client_handshaker_.get(), &peer),
TSI_OK);
CheckAlpn(&peer);
// TODO(jboeuf): This is a bit fragile. Maybe revisit.
if (config_.subject_name_indication != nullptr) {
CheckServer1Peer(&peer);
} else {
CheckServer0Peer(&peer);
}
} else {
EXPECT_NE(result, TSI_OK);
EXPECT_NE(tsi_handshaker_extract_peer(client_handshaker_.get(), &peer),
TSI_OK);
}
result = tsi_handshaker_get_result(server_handshaker_.get());
EXPECT_NE(result, TSI_HANDSHAKE_IN_PROGRESS);
if (expect_success) {
EXPECT_EQ(result, TSI_OK);
EXPECT_EQ(tsi_handshaker_extract_peer(server_handshaker_.get(), &peer),
TSI_OK);
CheckAlpn(&peer);
CheckClientPeer(&peer, config_.do_client_authentication);
} else {
EXPECT_NE(result, TSI_OK);
EXPECT_NE(tsi_handshaker_extract_peer(server_handshaker_.get(), &peer),
TSI_OK);
}
}
const tsi::test::TestConfig* config() override {
return &config_;
}
SslTransportSecurityTest()
: client_alpn_protocols_({"foo", "toto", "baz"}),
server_alpn_protocols_({"boooo", "far", "baz"}),
client_alpn_protocols_lengths_({3, 4, 3}),
server_alpn_protocols_lengths_({5, 3, 3}) {
CHECK_OK(file::GetContents(
file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "badserver.key"),
&badserver_key_, file::Options()));
CHECK_OK(file::GetContents(
file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "badserver.pem"),
&badserver_cert_, file::Options()));
CHECK_OK(file::GetContents(
file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "badclient.key"),
&badclient_key_, file::Options()));
CHECK_OK(file::GetContents(
file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "badclient.pem"),
&badclient_cert_, file::Options()));
CHECK_OK(file::GetContents(
file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "server0.key"),
&server0_key_, file::Options()));
CHECK_OK(file::GetContents(
file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "server0.pem"),
&server0_cert_, file::Options()));
CHECK_OK(file::GetContents(
file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "server1.key"),
&server1_key_, file::Options()));
CHECK_OK(file::GetContents(
file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "server1.pem"),
&server1_cert_, file::Options()));
CHECK_OK(file::GetContents(
file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "client.key"),
&client_key_, file::Options()));
CHECK_OK(file::GetContents(
file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "client.pem"),
&client_cert_, file::Options()));
CHECK_OK(file::GetContents(
file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "ca.pem"),
&root_certs_, file::Options()));
badserver_keys_.push_back(
reinterpret_cast<const unsigned char*>(badserver_key_.data()));
badserver_certs_.push_back(
reinterpret_cast<const unsigned char*>(badserver_cert_.data()));
server_keys_.push_back(
reinterpret_cast<const unsigned char*>(server0_key_.data()));
server_keys_.push_back(
reinterpret_cast<const unsigned char*>(server1_key_.data()));
server_certs_.push_back(
reinterpret_cast<const unsigned char*>(server0_cert_.data()));
server_certs_.push_back(
reinterpret_cast<const unsigned char*>(server1_cert_.data()));
badserver_keys_sizes_.push_back(badserver_key_.size());
badserver_certs_sizes_.push_back(badserver_cert_.size());
server_keys_sizes_.push_back(server0_key_.size());
server_keys_sizes_.push_back(server1_key_.size());
server_certs_sizes_.push_back(server0_cert_.size());
server_certs_sizes_.push_back(server1_cert_.size());
}
string badserver_key_;
string badserver_cert_;
string badclient_key_;
string badclient_cert_;
string server0_key_;
string server0_cert_;
string server1_key_;
string server1_cert_;
string client_key_;
string client_cert_;
string root_certs_;
std::vector<const unsigned char*> badserver_keys_;
std::vector<const unsigned char*> badserver_certs_;
std::vector<const unsigned char*> server_keys_;
std::vector<const unsigned char*> server_certs_;
std::vector<unsigned int> badserver_keys_sizes_;
std::vector<unsigned int> badserver_certs_sizes_;
std::vector<unsigned int> server_keys_sizes_;
std::vector<unsigned int> server_certs_sizes_;
TsiSslHandshakerFactoryUniquePtr client_handshaker_factory_;
TsiSslHandshakerFactoryUniquePtr server_handshaker_factory_;
std::vector<const char*> client_alpn_protocols_;
std::vector<const char*> server_alpn_protocols_;
std::vector<unsigned char> client_alpn_protocols_lengths_;
std::vector<unsigned char> server_alpn_protocols_lengths_;
string matched_alpn_;
SslTestConfig config_;
};
TEST_F(SslTransportSecurityTest, LoadInvalidRoots) {
tsi_ssl_handshaker_factory* client_handshaker_factory;
string invalid_roots("Invalid roots!");
EXPECT_EQ(
TSI_INVALID_ARGUMENT,
tsi_create_ssl_client_handshaker_factory(
NULL, 0, NULL, 0,
reinterpret_cast<const unsigned char*>(invalid_roots.data()),
invalid_roots.size(), NULL, NULL, 0, 0, &client_handshaker_factory));
}
TEST_F(SslTransportSecurityTest, Handshake) {
PerformHandshake();
}
TEST_F(SslTransportSecurityTest, HandshakeClientAuthentication) {
config_.do_client_authentication = true;
PerformHandshake();
}
TEST_F(SslTransportSecurityTest, HandshakeSmallBuffer) {
config_.handshake_buffer_size = 128;
PerformHandshake();
}
TEST_F(SslTransportSecurityTest, HandshakeSNIExactDomain) {
// server1 cert contains waterzooi.test.google.be in SAN.
config_.subject_name_indication = "waterzooi.test.google.be";
PerformHandshake();
}
TEST_F(SslTransportSecurityTest, HandshakeSNIWildstarDomain) {
// server1 cert contains *.test.google.fr in SAN.
config_.subject_name_indication = "juju.test.google.fr";
PerformHandshake();
}
TEST_F(SslTransportSecurityTest, BadServerCertFailure) {
config_.use_bad_server_cert = true;
PerformHandshake();
}
TEST_F(SslTransportSecurityTest, BadClientCertFailure) {
config_.use_bad_client_cert = true;
config_.do_client_authentication = true;
PerformHandshake();
}
TEST_F(SslTransportSecurityTest, AlpnClientNoServer) {
config_.alpn_mode = ALPN_CLIENT_NO_SERVER;
PerformHandshake();
}
TEST_F(SslTransportSecurityTest, AlpnServerNoClient) {
config_.alpn_mode = ALPN_SERVER_NO_CLIENT;
PerformHandshake();
}
TEST_F(SslTransportSecurityTest, AlpnClientServeMismatch) {
config_.alpn_mode = ALPN_CLIENT_SERVER_MISMATCH;
PerformHandshake();
}
TEST_F(SslTransportSecurityTest, AlpnClientServerOk) {
config_.alpn_mode = ALPN_CLIENT_SERVER_OK;
PerformHandshake();
}
TEST_F(SslTransportSecurityTest, PingPong) {
PingPong();
}
TEST_F(SslTransportSecurityTest, RoundTrip) {
config_.client_message = big_message_;
config_.server_message = small_message_;
DoRoundTrip();
}
TEST_F(SslTransportSecurityTest, RoundTripSmallMessageBuffer) {
config_.message_buffer_allocated_size = 42;
config_.client_message = big_message_;
config_.server_message = small_message_;
DoRoundTrip();
}
TEST_F(SslTransportSecurityTest, RoundTripSmallProtectedBufferSize) {
config_.protected_buffer_size = 37;
config_.client_message = big_message_;
config_.server_message = small_message_;
DoRoundTrip();
}
TEST_F(SslTransportSecurityTest, RoundTripSmallReadBufferSize) {
config_.read_buffer_allocated_size = 41;
config_.client_message = big_message_;
config_.server_message = small_message_;
DoRoundTrip();
}
TEST_F(SslTransportSecurityTest, RoundTripSmallClientFrames) {
config_.set_client_max_output_protected_frame_size(39);
config_.client_message = big_message_;
config_.server_message = small_message_;
DoRoundTrip();
}
TEST_F(SslTransportSecurityTest, RoundTripSmallServerFrames) {
config_.set_server_max_output_protected_frame_size(43);
config_.client_message = small_message_;
config_.server_message = big_message_;
DoRoundTrip();
}
TEST_F(SslTransportSecurityTest, RoundTripOddBufferSizes) {
int odd_sizes[] = {33, 67, 135, 271, 523};
RandomPermutation<int> permute(odd_sizes, arraysize(odd_sizes),
random_.get());
permute.Permute();
LOG(ERROR) << odd_sizes[0] << "\t" << odd_sizes[1] << "\t" << odd_sizes[2]
<< "\t" << odd_sizes[3] << "\t" << odd_sizes[4];
config_.message_buffer_allocated_size = odd_sizes[0];
config_.protected_buffer_size = odd_sizes[1];
config_.read_buffer_allocated_size = odd_sizes[2];
config_.set_client_max_output_protected_frame_size(odd_sizes[3]);
config_.set_server_max_output_protected_frame_size(odd_sizes[4]);
config_.client_message = big_message_;
config_.server_message = small_message_;
DoRoundTrip();
}
} // namespace

@ -180,23 +180,6 @@ void tsi_frame_protector_destroy(tsi_frame_protector* self);
/* This property is of type TSI_PEER_PROPERTY_STRING. */
#define TSI_CERTIFICATE_TYPE_PEER_PROPERTY "certificate_type"
/* This property is of type TSI_PEER_PROPERTY_STRING. */
#define TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY "x509_subject_common_name"
/* This property is of type TSI_PEER_PROPERTY_LIST and the children contain
unnamed (name == NULL) properties of type TSI_PEER_PROPERTY_STRING. */
#define TSI_X509_SUBJECT_ALTERNATIVE_NAMES_PEER_PROPERTY \
"x509_subject_alternative_names"
/* This property is of type TSI_PEER_PROPERTY_STRING. */
#define TSI_SSL_ALPN_SELECTED_PROTOCOL "ssl_alpn_selected_protocol"
/* This property is of type TSI_PEER_PROPERTY_STRING. */
#define TSI_MDB_USER_NAME_PEER_PROPERTY "mdb_user_name"
/* This property is of type TSI_PEER_PROPERTY_SIGNED_INTEGER. */
#define TSI_MDB_GAIA_ID_PEER_PROPERTY "mdb_gaia_id"
/* Properties of type TSI_PEER_PROPERTY_TYPE_STRING may contain NULL characters
just like C++ strings. The length field gives the length of the string. */
typedef enum {

@ -1,363 +0,0 @@
/*
*
* Copyright 2014, 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/tsi/transport_security_test_lib.h"
#include <memory>
#include "base/commandlineflags.h"
#include "src/core/tsi/transport_security_interface.h"
#include "strings/escaping.h"
#include "strings/strcat.h"
#include <gtest/gtest.h>
#include "util/random/mt_random.h"
namespace {
const char kPingRequest[] = "Ping";
const char kPongResponse[] = "Pong";
const int kBigMessageSize = 17000;
} // namespace
namespace tsi {
namespace test {
TransportSecurityTest::TransportSecurityTest() : random_(new MTRandom()) {
small_message_ = "Chapi Chapo";
big_message_ = RandomString(kBigMessageSize);
}
string TransportSecurityTest::RandomString(int size) {
std::unique_ptr<char[]> buffer(new char[size]);
for (int i = 0; i < size; i++) {
buffer[i] = random_->Rand8();
}
return string(buffer.get(), size);
}
void TransportSecurityTest::SendBytesToPeer(bool is_client, unsigned char* buf,
unsigned int buf_size) {
string& channel = is_client ? to_server_channel_ : to_client_channel_;
LOG(INFO) << (is_client ? "Client:" : "Server") << " sending " << buf_size
<< " bytes to peer.";
channel.append(reinterpret_cast<const char*>(buf), buf_size);
}
void TransportSecurityTest::ReadBytesFromPeer(bool is_client,
unsigned char* buf,
unsigned int* buf_size) {
string& channel = is_client ? to_client_channel_ : to_server_channel_;
unsigned int to_read =
*buf_size < channel.size() ? *buf_size : channel.size();
memcpy(buf, channel.data(), to_read);
*buf_size = to_read;
channel.erase(0, to_read);
LOG(INFO) << (is_client ? "Client:" : "Server") << " read " << to_read
<< " bytes from peer.";
}
void TransportSecurityTest::DoHandshakeStep(bool is_client,
unsigned int buf_allocated_size,
tsi_handshaker* handshaker,
string* remaining_bytes) {
tsi_result result = TSI_OK;
std::unique_ptr<unsigned char[]> buf(new unsigned char[buf_allocated_size]);
unsigned int buf_offset;
unsigned int buf_size;
// See if we need to send some bytes to the peer.
do {
unsigned int buf_size_to_send = buf_allocated_size;
result = tsi_handshaker_get_bytes_to_send_to_peer(handshaker, buf.get(),
&buf_size_to_send);
if (buf_size_to_send > 0) {
SendBytesToPeer(is_client, buf.get(), buf_size_to_send);
}
} while (result == TSI_INCOMPLETE_DATA);
if (!tsi_handshaker_is_in_progress(handshaker)) return;
do {
// Read bytes from the peer.
buf_size = buf_allocated_size;
buf_offset = 0;
ReadBytesFromPeer(is_client, buf.get(), &buf_size);
if (buf_size == 0) break;
// Process the bytes from the peer. We have to be careful as these bytes
// may contain non-handshake data (protected data). If this is the case,
// we will exit from the loop with buf_size > 0.
unsigned int consumed_by_handshaker = buf_size;
result = tsi_handshaker_process_bytes_from_peer(handshaker, buf.get(),
&consumed_by_handshaker);
buf_size -= consumed_by_handshaker;
buf_offset += consumed_by_handshaker;
} while (result == TSI_INCOMPLETE_DATA);
if (!tsi_handshaker_is_in_progress(handshaker)) {
remaining_bytes->assign(
reinterpret_cast<const char*>(buf.get()) + buf_offset, buf_size);
}
}
void TransportSecurityTest::PerformHandshake() {
SetupHandshakers();
string remaining_bytes;
do {
DoHandshakeStep(true, config()->handshake_buffer_size,
client_handshaker_.get(), &remaining_bytes);
EXPECT_EQ(0, remaining_bytes.size());
DoHandshakeStep(false, config()->handshake_buffer_size,
server_handshaker_.get(), &remaining_bytes);
EXPECT_EQ(0, remaining_bytes.size());
} while (tsi_handshaker_is_in_progress(client_handshaker_.get()) ||
tsi_handshaker_is_in_progress(server_handshaker_.get()));
CheckHandshakeResults();
}
void TransportSecurityTest::SendMessageToPeer(
bool is_client, tsi_frame_protector* protector, const string& message,
unsigned int protected_buffer_size) {
std::unique_ptr<unsigned char[]> protected_buffer(
new unsigned char[protected_buffer_size]);
unsigned int message_size = message.size();
const unsigned char* message_bytes =
reinterpret_cast<const unsigned char*>(message.data());
tsi_result result = TSI_OK;
while (message_size > 0 && result == TSI_OK) {
unsigned int protected_buffer_size_to_send = protected_buffer_size;
unsigned int processed_message_size = message_size;
result = tsi_frame_protector_protect(
protector, message_bytes, &processed_message_size,
protected_buffer.get(), &protected_buffer_size_to_send);
EXPECT_EQ(TSI_OK, result);
SendBytesToPeer(is_client, protected_buffer.get(),
protected_buffer_size_to_send);
message_bytes += processed_message_size;
message_size -= processed_message_size;
// Flush if we're done.
if (message_size == 0) {
unsigned int still_pending_size;
do {
protected_buffer_size_to_send = protected_buffer_size;
result = tsi_frame_protector_protect_flush(
protector, protected_buffer.get(), &protected_buffer_size_to_send,
&still_pending_size);
EXPECT_EQ(TSI_OK, result);
SendBytesToPeer(is_client, protected_buffer.get(),
protected_buffer_size_to_send);
} while (still_pending_size > 0 && result == TSI_OK);
EXPECT_EQ(TSI_OK, result);
}
}
EXPECT_EQ(TSI_OK, result);
}
void TransportSecurityTest::ReceiveMessageFromPeer(
bool is_client, tsi_frame_protector* protector,
unsigned int read_buf_allocated_size,
unsigned int message_buf_allocated_size, string* message) {
std::unique_ptr<unsigned char[]> read_buffer(
new unsigned char[read_buf_allocated_size]);
unsigned int read_offset = 0;
unsigned int read_from_peer_size = 0;
std::unique_ptr<unsigned char[]> message_buffer(
new unsigned char[message_buf_allocated_size]);
tsi_result result = TSI_OK;
bool done = false;
while (!done && result == TSI_OK) {
if (read_from_peer_size == 0) {
read_from_peer_size = read_buf_allocated_size;
ReadBytesFromPeer(is_client, read_buffer.get(), &read_from_peer_size);
read_offset = 0;
}
if (read_from_peer_size == 0) done = true;
unsigned int message_buffer_size;
do {
message_buffer_size = message_buf_allocated_size;
unsigned int processed_size = read_from_peer_size;
result = tsi_frame_protector_unprotect(
protector, read_buffer.get() + read_offset, &processed_size,
message_buffer.get(), &message_buffer_size);
EXPECT_EQ(TSI_OK, result);
if (message_buffer_size > 0) {
LOG(INFO) << "Wrote " << message_buffer_size << " bytes to message.";
message->append(reinterpret_cast<const char*>(message_buffer.get()),
message_buffer_size);
}
read_offset += processed_size;
read_from_peer_size -= processed_size;
} while ((read_from_peer_size > 0 || message_buffer_size > 0) &&
result == TSI_OK);
EXPECT_EQ(TSI_OK, result);
}
EXPECT_EQ(TSI_OK, result);
}
void TransportSecurityTest::DoRoundTrip(const string& request,
const string& response) {
PerformHandshake();
tsi_frame_protector* client_frame_protector;
tsi_frame_protector* server_frame_protector;
unsigned int client_max_output_protected_frame_size =
config()->client_max_output_protected_frame_size();
EXPECT_EQ(TSI_OK,
tsi_handshaker_create_frame_protector(
client_handshaker_.get(),
config()->use_client_default_max_output_protected_frame_size()
? nullptr
: &client_max_output_protected_frame_size,
&client_frame_protector));
unsigned int server_max_output_protected_frame_size =
config()->server_max_output_protected_frame_size();
EXPECT_EQ(TSI_OK,
tsi_handshaker_create_frame_protector(
server_handshaker_.get(),
config()->use_server_default_max_output_protected_frame_size()
? nullptr
: &server_max_output_protected_frame_size,
&server_frame_protector));
SendMessageToPeer(true, client_frame_protector, request,
config()->protected_buffer_size);
string retrieved_request;
ReceiveMessageFromPeer(
false, server_frame_protector, config()->read_buffer_allocated_size,
config()->message_buffer_allocated_size, &retrieved_request);
EXPECT_EQ(request.size(), retrieved_request.size());
EXPECT_EQ(strings::b2a_hex(request), strings::b2a_hex(retrieved_request));
SendMessageToPeer(false, server_frame_protector, response,
config()->protected_buffer_size);
string retrieved_response;
ReceiveMessageFromPeer(
true, client_frame_protector, config()->read_buffer_allocated_size,
config()->message_buffer_allocated_size, &retrieved_response);
EXPECT_EQ(response.size(), retrieved_response.size());
EXPECT_EQ(strings::b2a_hex(response), strings::b2a_hex(retrieved_response));
tsi_frame_protector_destroy(client_frame_protector);
tsi_frame_protector_destroy(server_frame_protector);
}
void TransportSecurityTest::DoRoundTrip() {
DoRoundTrip(config()->client_message, config()->server_message);
}
void TransportSecurityTest::PingPong() {
PerformHandshake();
unsigned char to_server[4096];
unsigned char to_client[4096];
unsigned int max_frame_size = sizeof(to_client);
tsi_frame_protector* client_frame_protector;
tsi_frame_protector* server_frame_protector;
EXPECT_EQ(
tsi_handshaker_create_frame_protector(
client_handshaker_.get(), &max_frame_size, &client_frame_protector),
TSI_OK);
EXPECT_EQ(max_frame_size, sizeof(to_client));
EXPECT_EQ(
tsi_handshaker_create_frame_protector(
server_handshaker_.get(), &max_frame_size, &server_frame_protector),
TSI_OK);
EXPECT_EQ(max_frame_size, sizeof(to_client));
// Send Ping.
unsigned int ping_length = strlen(kPingRequest);
unsigned int protected_size = sizeof(to_server);
EXPECT_EQ(tsi_frame_protector_protect(
client_frame_protector,
reinterpret_cast<const unsigned char*>(kPingRequest),
&ping_length, to_server, &protected_size),
TSI_OK);
EXPECT_EQ(ping_length, strlen(kPingRequest));
EXPECT_EQ(protected_size, 0);
protected_size = sizeof(to_server);
unsigned int still_pending_size;
EXPECT_EQ(
tsi_frame_protector_protect_flush(client_frame_protector, to_server,
&protected_size, &still_pending_size),
TSI_OK);
EXPECT_EQ(still_pending_size, 0);
EXPECT_GT(protected_size, strlen(kPingRequest));
// Receive Ping.
unsigned int unprotected_size = sizeof(to_server);
unsigned int saved_protected_size = protected_size;
EXPECT_EQ(tsi_frame_protector_unprotect(server_frame_protector, to_server,
&protected_size, to_server,
&unprotected_size),
TSI_OK);
EXPECT_EQ(saved_protected_size, protected_size);
EXPECT_EQ(ping_length, unprotected_size);
EXPECT_EQ(string(kPingRequest),
string(reinterpret_cast<const char*>(to_server), unprotected_size));
// Send back Pong.
unsigned int pong_length = strlen(kPongResponse);
protected_size = sizeof(to_client);
EXPECT_EQ(tsi_frame_protector_protect(
server_frame_protector,
reinterpret_cast<const unsigned char*>(kPongResponse),
&pong_length, to_client, &protected_size),
TSI_OK);
EXPECT_EQ(pong_length, strlen(kPongResponse));
EXPECT_EQ(protected_size, 0);
protected_size = sizeof(to_client);
EXPECT_EQ(
tsi_frame_protector_protect_flush(server_frame_protector, to_client,
&protected_size, &still_pending_size),
TSI_OK);
EXPECT_EQ(still_pending_size, 0);
EXPECT_GT(protected_size, strlen(kPongResponse));
// Receive Pong.
unprotected_size = sizeof(to_server);
saved_protected_size = protected_size;
EXPECT_EQ(tsi_frame_protector_unprotect(client_frame_protector, to_client,
&protected_size, to_client,
&unprotected_size),
TSI_OK);
EXPECT_EQ(saved_protected_size, protected_size);
EXPECT_EQ(pong_length, unprotected_size);
EXPECT_EQ(string(kPongResponse),
string(reinterpret_cast<const char*>(to_client), unprotected_size));
tsi_frame_protector_destroy(client_frame_protector);
tsi_frame_protector_destroy(server_frame_protector);
}
} // namespace test
} // namespace tsi

@ -1,154 +0,0 @@
/*
*
* Copyright 2014, 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 __TRANSPORT_SECURITY_TEST_LIB_H_
#define __TRANSPORT_SECURITY_TEST_LIB_H_
#include <memory>
#include "base/commandlineflags.h"
#include "src/core/tsi/transport_security_interface.h"
#include "strings/strcat.h"
#include <gtest/gtest.h>
#include "util/random/mt_random.h"
namespace tsi {
namespace test {
class TestConfig {
public:
TestConfig()
: client_message("Chapi Chapo"),
server_message("Chapi Chapo"),
handshake_buffer_size(4096),
read_buffer_allocated_size(4096),
message_buffer_allocated_size(4096),
protected_buffer_size(16384),
use_client_default_max_output_protected_frame_size_(true),
use_server_default_max_output_protected_frame_size_(true),
client_max_output_protected_frame_size_(0),
server_max_output_protected_frame_size_(0) {}
void set_client_max_output_protected_frame_size(unsigned int size) {
use_client_default_max_output_protected_frame_size_ = false;
client_max_output_protected_frame_size_ = size;
}
void set_server_max_output_protected_frame_size(unsigned int size) {
use_server_default_max_output_protected_frame_size_ = false;
server_max_output_protected_frame_size_ = size;
}
bool use_client_default_max_output_protected_frame_size() const {
return use_client_default_max_output_protected_frame_size_;
}
bool use_server_default_max_output_protected_frame_size() const {
return use_server_default_max_output_protected_frame_size_;
}
unsigned int client_max_output_protected_frame_size() const {
return client_max_output_protected_frame_size_;
}
unsigned int server_max_output_protected_frame_size() const {
return server_max_output_protected_frame_size_;
}
string client_message;
string server_message;
unsigned int handshake_buffer_size;
unsigned int read_buffer_allocated_size;
unsigned int message_buffer_allocated_size;
unsigned int protected_buffer_size;
private:
bool use_client_default_max_output_protected_frame_size_;
bool use_server_default_max_output_protected_frame_size_;
unsigned int client_max_output_protected_frame_size_;
unsigned int server_max_output_protected_frame_size_;
};
struct TsiHandshakerDeleter {
inline void operator()(tsi_handshaker* ptr) { tsi_handshaker_destroy(ptr); }
};
typedef std::unique_ptr<tsi_handshaker, TsiHandshakerDeleter>
TsiHandshakerUniquePtr;
class TransportSecurityTest : public ::testing::Test {
protected:
TransportSecurityTest();
virtual ~TransportSecurityTest() {}
virtual const TestConfig* config() = 0;
string RandomString(int size);
virtual void SetupHandshakers() = 0;
// An implementation-specific verification of the validity of the handshake.
virtual void CheckHandshakeResults() = 0;
// Do a full handshake.
void PerformHandshake();
// Send a protected message between the client and server.
void SendMessageToPeer(bool is_client, tsi_frame_protector* protector,
const string& message,
unsigned int protected_buffer_size);
void ReceiveMessageFromPeer(bool is_client, tsi_frame_protector* protector,
unsigned int read_buf_allocated_size,
unsigned int message_buf_allocated_size,
string* message);
// A simple test that does a handshake and sends a message back and forth
void PingPong();
// A complicated test that can be configured by modifying config().
void DoRoundTrip();
TsiHandshakerUniquePtr client_handshaker_;
TsiHandshakerUniquePtr server_handshaker_;
string small_message_;
string big_message_;
std::unique_ptr<RandomBase> random_;
private:
// Functions to send raw bytes between the client and server.
void SendBytesToPeer(bool is_client, unsigned char* buf,
unsigned int buf_size);
void ReadBytesFromPeer(bool is_client, unsigned char* buf,
unsigned int* buf_size);
// Do a single step of the handshake.
void DoHandshakeStep(bool is_client, unsigned int buf_allocated_size,
tsi_handshaker* handshaker, string* remaining_bytes);
void DoRoundTrip(const string& request, const string& response);
string to_server_channel_;
string to_client_channel_;
};
} // namespace test
} // namespace tsi
#endif // __TRANSPORT_SECURITY_TEST_LIB_H_

@ -0,0 +1,2 @@
<%namespace file="vcxproj_defs.include" import="gen_project"/>\
${gen_project('gpr_test_util', libs, targets)}

@ -73,26 +73,35 @@ void test_connect(const char *server_host, const char *client_host, int port,
cq_verifier *v_client;
cq_verifier *v_server;
gpr_timespec deadline;
int got_port;
gpr_join_host_port(&client_hostport, client_host, port);
gpr_join_host_port(&server_hostport, server_host, port);
gpr_log(GPR_INFO, "Testing with server=%s client=%s (expecting %s)",
server_hostport, client_hostport, expect_ok ? "success" : "failure");
/* Create server. */
server_cq = grpc_completion_queue_create();
server = grpc_server_create(server_cq, NULL);
GPR_ASSERT(grpc_server_add_http2_port(server, server_hostport));
GPR_ASSERT((got_port = grpc_server_add_http2_port(server, server_hostport)) >
0);
if (port == 0) {
port = got_port;
} else {
GPR_ASSERT(port == got_port);
}
grpc_server_start(server);
gpr_free(server_hostport);
v_server = cq_verifier_create(server_cq);
/* Create client. */
gpr_join_host_port(&client_hostport, client_host, port);
client_cq = grpc_completion_queue_create();
client = grpc_channel_create(client_hostport, NULL);
gpr_free(client_hostport);
v_client = cq_verifier_create(client_cq);
gpr_log(GPR_INFO, "Testing with server=%s client=%s (expecting %s)",
server_hostport, client_hostport, expect_ok ? "success" : "failure");
gpr_free(client_hostport);
gpr_free(server_hostport);
if (expect_ok) {
/* Normal deadline, shouldn't be reached. */
deadline = ms_from_now(60000);
@ -170,8 +179,7 @@ void test_connect(const char *server_host, const char *client_host, int port,
int main(int argc, char **argv) {
int do_ipv6 = 1;
int i;
int port = grpc_pick_unused_port_or_die();
int fixed_port;
grpc_test_init(argc, argv);
grpc_init();
@ -181,30 +189,34 @@ int main(int argc, char **argv) {
do_ipv6 = 0;
}
for (i = 0; i <= 1; i++) {
for (fixed_port = 0; fixed_port <= 1; fixed_port++) {
int port = fixed_port ? grpc_pick_unused_port_or_die() : 0;
/* For coverage, test with and without dualstack sockets. */
grpc_forbid_dualstack_sockets_for_testing = i;
/* :: and 0.0.0.0 are handled identically. */
test_connect("::", "127.0.0.1", port, 1);
test_connect("::", "::ffff:127.0.0.1", port, 1);
test_connect("::", "localhost", port, 1);
test_connect("0.0.0.0", "127.0.0.1", port, 1);
test_connect("0.0.0.0", "::ffff:127.0.0.1", port, 1);
test_connect("0.0.0.0", "localhost", port, 1);
if (do_ipv6) {
test_connect("::", "::1", port, 1);
test_connect("0.0.0.0", "::1", port, 1);
}
for (grpc_forbid_dualstack_sockets_for_testing = 0;
grpc_forbid_dualstack_sockets_for_testing <= 1;
grpc_forbid_dualstack_sockets_for_testing++) {
/* :: and 0.0.0.0 are handled identically. */
test_connect("::", "127.0.0.1", port, 1);
test_connect("::", "::ffff:127.0.0.1", port, 1);
test_connect("::", "localhost", port, 1);
test_connect("0.0.0.0", "127.0.0.1", port, 1);
test_connect("0.0.0.0", "::ffff:127.0.0.1", port, 1);
test_connect("0.0.0.0", "localhost", port, 1);
if (do_ipv6) {
test_connect("::", "::1", port, 1);
test_connect("0.0.0.0", "::1", port, 1);
}
/* These only work when the families agree. */
test_connect("127.0.0.1", "127.0.0.1", port, 1);
if (do_ipv6) {
test_connect("::1", "::1", port, 1);
test_connect("::1", "127.0.0.1", port, 0);
test_connect("127.0.0.1", "::1", port, 0);
}
/* These only work when the families agree. */
test_connect("127.0.0.1", "127.0.0.1", port, 1);
if (do_ipv6) {
test_connect("::1", "::1", port, 1);
test_connect("::1", "127.0.0.1", port, 0);
test_connect("127.0.0.1", "::1", port, 0);
}
}
grpc_shutdown();

@ -80,6 +80,7 @@ def main():
'end2end_certs',
'grpc_test_util',
'grpc',
'gpr_test_util',
'gpr'
]
}

@ -46,7 +46,7 @@
#include <grpc++/client_context.h>
#include <grpc++/status.h>
#include "test/cpp/util/create_test_channel.h"
#include "test/cpp/interop/test.pb.h"
#include "test/cpp/qps/qpstest.pb.h"
DEFINE_bool(enable_ssl, false, "Whether to use ssl/tls.");
DEFINE_int32(server_port, 0, "Server port.");
@ -74,8 +74,10 @@ DEFINE_string(workload, "", "Workload parameters");
using grpc::ChannelInterface;
using grpc::CreateTestChannel;
using grpc::testing::ServerStats;
using grpc::testing::SimpleRequest;
using grpc::testing::SimpleResponse;
using grpc::testing::StatsRequest;
using grpc::testing::TestService;
static double now() {
@ -120,6 +122,14 @@ void RunTest(const int client_threads, const int client_channels,
std::vector<std::thread> threads; // Will add threads when ready to execute
std::vector<::gpr_histogram *> thread_stats(client_threads);
TestService::Stub *stub_stats = channels[0].get_stub();
grpc::ClientContext context_stats_begin;
StatsRequest stats_request;
ServerStats server_stats_begin;
stats_request.set_test_num(0);
grpc::Status status_beg = stub_stats->CollectServerStats(
&context_stats_begin, stats_request, &server_stats_begin);
for (int i = 0; i < client_threads; i++) {
gpr_histogram *hist = gpr_histogram_create(0.01, 60e9);
GPR_ASSERT(hist != NULL);
@ -161,11 +171,9 @@ void RunTest(const int client_threads, const int client_channels,
}
for (int i = 0; i < client_threads; i++) {
gpr_histogram *h = thread_stats[i];
gpr_log(GPR_INFO, "latency at thread %d (50/95/99/99.9): %f/%f/%f/%f",
i,
gpr_histogram_percentile(h, 50),
gpr_histogram_percentile(h, 95),
gpr_histogram_percentile(h, 99),
gpr_log(GPR_INFO, "latency at thread %d (50/90/95/99/99.9): %f/%f/%f/%f/%f",
i, gpr_histogram_percentile(h, 50), gpr_histogram_percentile(h, 90),
gpr_histogram_percentile(h, 95), gpr_histogram_percentile(h, 99),
gpr_histogram_percentile(h, 99.9));
gpr_histogram_merge(hist, h);
gpr_histogram_destroy(h);
@ -174,11 +182,32 @@ void RunTest(const int client_threads, const int client_channels,
gpr_log(
GPR_INFO,
"latency across %d threads with %d channels and %d payload "
"(50/95/99/99.9): %f / %f / %f / %f",
"(50/90/95/99/99.9): %f / %f / %f / %f / %f",
client_threads, client_channels, payload_size,
gpr_histogram_percentile(hist, 50), gpr_histogram_percentile(hist, 95),
gpr_histogram_percentile(hist, 99), gpr_histogram_percentile(hist, 99.9));
gpr_histogram_percentile(hist, 50), gpr_histogram_percentile(hist, 90),
gpr_histogram_percentile(hist, 95), gpr_histogram_percentile(hist, 99),
gpr_histogram_percentile(hist, 99.9));
gpr_histogram_destroy(hist);
grpc::ClientContext context_stats_end;
ServerStats server_stats_end;
grpc::Status status_end = stub_stats->CollectServerStats(
&context_stats_end, stats_request, &server_stats_end);
double elapsed = server_stats_end.time_now() - server_stats_begin.time_now();
int total_rpcs = client_threads * num_rpcs;
double utime = server_stats_end.time_user() - server_stats_begin.time_user();
double stime =
server_stats_end.time_system() - server_stats_begin.time_system();
gpr_log(GPR_INFO,
"Elapsed time: %.3f\n"
"RPC Count: %d\n"
"QPS: %.3f\n"
"System time: %.3f\n"
"User time: %.3f\n"
"Resource usage: %.1f%%\n",
elapsed, total_rpcs, total_rpcs / elapsed, stime, utime,
(stime + utime) / elapsed * 100.0);
}
int main(int argc, char **argv) {

@ -0,0 +1,162 @@
// An integration test service that covers all the method signature permutations
// of unary/streaming requests/responses.
syntax = "proto2";
package grpc.testing;
option java_api_version = 2;
option cc_api_version = 2;
option java_package = "com.google.net.stubby.testing.integration";
enum PayloadType {
// Compressable text format.
COMPRESSABLE= 1;
// Uncompressable binary format.
UNCOMPRESSABLE = 2;
// Randomly chosen from all other formats defined in this enum.
RANDOM = 3;
}
message StatsRequest {
// run number
optional int32 test_num = 1;
}
message ServerStats {
// wall clock time for timestamp
required double time_now = 1;
// user time used by the server process and threads
required double time_user = 2;
// server time used by the server process and all threads
required double time_system = 3;
// RPC count so far
optional int32 num_rpcs = 4;
}
message Payload {
// The type of data in body.
optional PayloadType type = 1;
// Primary contents of payload.
optional bytes body = 2;
}
message Latencies {
required double l_50 = 1;
required double l_90 = 2;
required double l_99 = 3;
required double l_999 = 4;
}
message StartArgs {
required string server_host = 1;
required int32 server_port = 2;
optional bool enable_ssl = 3 [default = false];
optional int32 client_threads = 4 [default = 1];
optional int32 client_channels = 5 [default = -1];
optional int32 num_rpcs = 6 [default = 1];
optional int32 payload_size = 7 [default = 1];
}
message StartResult {
required Latencies latencies = 1;
required int32 num_rpcs = 2;
required double time_elapsed = 3;
required double time_user = 4;
required double time_system = 5;
}
message SimpleRequest {
// Desired payload type in the response from the server.
// If response_type is RANDOM, server randomly chooses one from other formats.
optional PayloadType response_type = 1 [default=COMPRESSABLE];
// Desired payload size in the response from the server.
// If response_type is COMPRESSABLE, this denotes the size before compression.
optional int32 response_size = 2;
// Optional input payload sent along with the request.
optional Payload payload = 3;
}
message SimpleResponse {
optional Payload payload = 1;
}
message StreamingInputCallRequest {
// Optional input payload sent along with the request.
optional Payload payload = 1;
// Not expecting any payload from the response.
}
message StreamingInputCallResponse {
// Aggregated size of payloads received from the client.
optional int32 aggregated_payload_size = 1;
}
message ResponseParameters {
// Desired payload sizes in responses from the server.
// If response_type is COMPRESSABLE, this denotes the size before compression.
required int32 size = 1;
// Desired interval between consecutive responses in the response stream in
// microseconds.
required int32 interval_us = 2;
}
message StreamingOutputCallRequest {
// Desired payload type in the response from the server.
// If response_type is RANDOM, the payload from each response in the stream
// might be of different types. This is to simulate a mixed type of payload
// stream.
optional PayloadType response_type = 1 [default=COMPRESSABLE];
repeated ResponseParameters response_parameters = 2;
// Optional input payload sent along with the request.
optional Payload payload = 3;
}
message StreamingOutputCallResponse {
optional Payload payload = 1;
}
service TestService {
// Start test with specified workload
rpc StartTest(StartArgs) returns (Latencies);
// Collect stats from server, ignore request content
rpc CollectServerStats(StatsRequest) returns (ServerStats);
// One request followed by one response.
// The server returns the client payload as-is.
rpc UnaryCall(SimpleRequest) returns (SimpleResponse);
// One request followed by a sequence of responses (streamed download).
// The server returns the payload with client desired type and sizes.
rpc StreamingOutputCall(StreamingOutputCallRequest)
returns (stream StreamingOutputCallResponse);
// A sequence of requests followed by one response (streamed upload).
// The server returns the aggregated size of client payload as the result.
rpc StreamingInputCall(stream StreamingInputCallRequest)
returns (StreamingInputCallResponse);
// A sequence of requests with each request served by the server immediately.
// As one request could lead to multiple responses, this interface
// demonstrates the idea of full duplexing.
rpc FullDuplexCall(stream StreamingOutputCallRequest)
returns (stream StreamingOutputCallResponse);
// A sequence of requests followed by a sequence of responses.
// The server buffers all the client requests and then serves them in order. A
// stream of responses are returned to the client when the server starts with
// first request.
rpc HalfDuplexCall(stream StreamingOutputCallRequest)
returns (stream StreamingOutputCallResponse);
}

@ -31,6 +31,8 @@
*
*/
#include <sys/time.h>
#include <sys/resource.h>
#include <thread>
#include <google/gflags.h>
@ -41,7 +43,7 @@
#include <grpc++/server_builder.h>
#include <grpc++/server_context.h>
#include <grpc++/status.h>
#include "test/cpp/interop/test.pb.h"
#include "test/cpp/qps/qpstest.pb.h"
#include <grpc/grpc.h>
#include <grpc/support/log.h>
@ -54,11 +56,17 @@ using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::testing::Payload;
using grpc::testing::PayloadType;
using grpc::testing::ServerStats;
using grpc::testing::SimpleRequest;
using grpc::testing::SimpleResponse;
using grpc::testing::StatsRequest;
using grpc::testing::TestService;
using grpc::Status;
static double time_double(struct timeval* tv) {
return tv->tv_sec + 1e-6 * tv->tv_usec;
}
bool SetPayload(PayloadType type, int size, Payload* payload) {
PayloadType response_type = type;
// TODO(yangg): Support UNCOMPRESSABLE payload.
@ -72,7 +80,21 @@ bool SetPayload(PayloadType type, int size, Payload* payload) {
}
class TestServiceImpl : public TestService::Service {
private:
int num_rpcs;
public:
Status CollectServerStats(ServerContext* context, const StatsRequest*,
ServerStats* response) {
struct rusage usage;
struct timeval tv;
gettimeofday(&tv, NULL);
getrusage(RUSAGE_SELF, &usage);
response->set_time_now(time_double(&tv));
response->set_time_user(time_double(&usage.ru_utime));
response->set_time_system(time_double(&usage.ru_stime));
return Status::OK;
}
Status UnaryCall(ServerContext* context, const SimpleRequest* request,
SimpleResponse* response) {
if (request->has_response_size() && request->response_size() > 0) {

@ -11,7 +11,7 @@ mkdir test_bin
echo Building test gpr_cancellable_test
cl.exe /c /I..\.. /I..\..\include /nologo /ZI /W3 /WX- /sdl /D WIN32 /D _LIB /D _USE_32BIT_TIME_T /D _UNICODE /D UNICODE /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /TC /analyze- /Fo:test_bin\ ..\..\test\core\support\cancellable_test.c
link.exe /OUT:"test_bin\gpr_cancellable_test.exe" /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 Debug\grpc_test_util.lib Debug\gpr.lib test_bin\cancellable_test.obj
link.exe /OUT:"test_bin\gpr_cancellable_test.exe" /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 Debug\gpr_test_util.lib Debug\gpr.lib test_bin\cancellable_test.obj
echo(
echo Running test gpr_cancellable_test
test_bin\gpr_cancellable_test.exe || echo TEST FAILED: gpr_cancellable_test && exit /b
@ -19,7 +19,7 @@ echo(
echo Building test gpr_log_test
cl.exe /c /I..\.. /I..\..\include /nologo /ZI /W3 /WX- /sdl /D WIN32 /D _LIB /D _USE_32BIT_TIME_T /D _UNICODE /D UNICODE /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /TC /analyze- /Fo:test_bin\ ..\..\test\core\support\log_test.c
link.exe /OUT:"test_bin\gpr_log_test.exe" /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 Debug\grpc_test_util.lib Debug\gpr.lib test_bin\log_test.obj
link.exe /OUT:"test_bin\gpr_log_test.exe" /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 Debug\gpr_test_util.lib Debug\gpr.lib test_bin\log_test.obj
echo(
echo Running test gpr_log_test
test_bin\gpr_log_test.exe || echo TEST FAILED: gpr_log_test && exit /b
@ -27,7 +27,7 @@ echo(
echo Building test gpr_useful_test
cl.exe /c /I..\.. /I..\..\include /nologo /ZI /W3 /WX- /sdl /D WIN32 /D _LIB /D _USE_32BIT_TIME_T /D _UNICODE /D UNICODE /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /TC /analyze- /Fo:test_bin\ ..\..\test\core\support\useful_test.c
link.exe /OUT:"test_bin\gpr_useful_test.exe" /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 Debug\grpc_test_util.lib Debug\gpr.lib test_bin\useful_test.obj
link.exe /OUT:"test_bin\gpr_useful_test.exe" /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 Debug\gpr_test_util.lib Debug\gpr.lib test_bin\useful_test.obj
echo(
echo Running test gpr_useful_test
test_bin\gpr_useful_test.exe || echo TEST FAILED: gpr_useful_test && exit /b
@ -35,7 +35,7 @@ echo(
echo Building test gpr_cmdline_test
cl.exe /c /I..\.. /I..\..\include /nologo /ZI /W3 /WX- /sdl /D WIN32 /D _LIB /D _USE_32BIT_TIME_T /D _UNICODE /D UNICODE /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /TC /analyze- /Fo:test_bin\ ..\..\test\core\support\cmdline_test.c
link.exe /OUT:"test_bin\gpr_cmdline_test.exe" /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 Debug\grpc_test_util.lib Debug\gpr.lib test_bin\cmdline_test.obj
link.exe /OUT:"test_bin\gpr_cmdline_test.exe" /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 Debug\gpr_test_util.lib Debug\gpr.lib test_bin\cmdline_test.obj
echo(
echo Running test gpr_cmdline_test
test_bin\gpr_cmdline_test.exe || echo TEST FAILED: gpr_cmdline_test && exit /b
@ -43,7 +43,7 @@ echo(
echo Building test gpr_histogram_test
cl.exe /c /I..\.. /I..\..\include /nologo /ZI /W3 /WX- /sdl /D WIN32 /D _LIB /D _USE_32BIT_TIME_T /D _UNICODE /D UNICODE /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /TC /analyze- /Fo:test_bin\ ..\..\test\core\support\histogram_test.c
link.exe /OUT:"test_bin\gpr_histogram_test.exe" /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 Debug\grpc_test_util.lib Debug\gpr.lib test_bin\histogram_test.obj
link.exe /OUT:"test_bin\gpr_histogram_test.exe" /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 Debug\gpr_test_util.lib Debug\gpr.lib test_bin\histogram_test.obj
echo(
echo Running test gpr_histogram_test
test_bin\gpr_histogram_test.exe || echo TEST FAILED: gpr_histogram_test && exit /b
@ -51,7 +51,7 @@ echo(
echo Building test gpr_host_port_test
cl.exe /c /I..\.. /I..\..\include /nologo /ZI /W3 /WX- /sdl /D WIN32 /D _LIB /D _USE_32BIT_TIME_T /D _UNICODE /D UNICODE /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /TC /analyze- /Fo:test_bin\ ..\..\test\core\support\host_port_test.c
link.exe /OUT:"test_bin\gpr_host_port_test.exe" /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 Debug\grpc_test_util.lib Debug\gpr.lib test_bin\host_port_test.obj
link.exe /OUT:"test_bin\gpr_host_port_test.exe" /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 Debug\gpr_test_util.lib Debug\gpr.lib test_bin\host_port_test.obj
echo(
echo Running test gpr_host_port_test
test_bin\gpr_host_port_test.exe || echo TEST FAILED: gpr_host_port_test && exit /b
@ -59,7 +59,7 @@ echo(
echo Building test gpr_slice_buffer_test
cl.exe /c /I..\.. /I..\..\include /nologo /ZI /W3 /WX- /sdl /D WIN32 /D _LIB /D _USE_32BIT_TIME_T /D _UNICODE /D UNICODE /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /TC /analyze- /Fo:test_bin\ ..\..\test\core\support\slice_buffer_test.c
link.exe /OUT:"test_bin\gpr_slice_buffer_test.exe" /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 Debug\grpc_test_util.lib Debug\gpr.lib test_bin\slice_buffer_test.obj
link.exe /OUT:"test_bin\gpr_slice_buffer_test.exe" /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 Debug\gpr_test_util.lib Debug\gpr.lib test_bin\slice_buffer_test.obj
echo(
echo Running test gpr_slice_buffer_test
test_bin\gpr_slice_buffer_test.exe || echo TEST FAILED: gpr_slice_buffer_test && exit /b
@ -67,7 +67,7 @@ echo(
echo Building test gpr_slice_test
cl.exe /c /I..\.. /I..\..\include /nologo /ZI /W3 /WX- /sdl /D WIN32 /D _LIB /D _USE_32BIT_TIME_T /D _UNICODE /D UNICODE /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /TC /analyze- /Fo:test_bin\ ..\..\test\core\support\slice_test.c
link.exe /OUT:"test_bin\gpr_slice_test.exe" /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 Debug\grpc_test_util.lib Debug\gpr.lib test_bin\slice_test.obj
link.exe /OUT:"test_bin\gpr_slice_test.exe" /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 Debug\gpr_test_util.lib Debug\gpr.lib test_bin\slice_test.obj
echo(
echo Running test gpr_slice_test
test_bin\gpr_slice_test.exe || echo TEST FAILED: gpr_slice_test && exit /b
@ -75,7 +75,7 @@ echo(
echo Building test gpr_string_test
cl.exe /c /I..\.. /I..\..\include /nologo /ZI /W3 /WX- /sdl /D WIN32 /D _LIB /D _USE_32BIT_TIME_T /D _UNICODE /D UNICODE /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /TC /analyze- /Fo:test_bin\ ..\..\test\core\support\string_test.c
link.exe /OUT:"test_bin\gpr_string_test.exe" /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 Debug\grpc_test_util.lib Debug\gpr.lib test_bin\string_test.obj
link.exe /OUT:"test_bin\gpr_string_test.exe" /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 Debug\gpr_test_util.lib Debug\gpr.lib test_bin\string_test.obj
echo(
echo Running test gpr_string_test
test_bin\gpr_string_test.exe || echo TEST FAILED: gpr_string_test && exit /b
@ -83,7 +83,7 @@ echo(
echo Building test gpr_sync_test
cl.exe /c /I..\.. /I..\..\include /nologo /ZI /W3 /WX- /sdl /D WIN32 /D _LIB /D _USE_32BIT_TIME_T /D _UNICODE /D UNICODE /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /TC /analyze- /Fo:test_bin\ ..\..\test\core\support\sync_test.c
link.exe /OUT:"test_bin\gpr_sync_test.exe" /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 Debug\grpc_test_util.lib Debug\gpr.lib test_bin\sync_test.obj
link.exe /OUT:"test_bin\gpr_sync_test.exe" /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 Debug\gpr_test_util.lib Debug\gpr.lib test_bin\sync_test.obj
echo(
echo Running test gpr_sync_test
test_bin\gpr_sync_test.exe || echo TEST FAILED: gpr_sync_test && exit /b
@ -91,7 +91,7 @@ echo(
echo Building test gpr_thd_test
cl.exe /c /I..\.. /I..\..\include /nologo /ZI /W3 /WX- /sdl /D WIN32 /D _LIB /D _USE_32BIT_TIME_T /D _UNICODE /D UNICODE /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /TC /analyze- /Fo:test_bin\ ..\..\test\core\support\thd_test.c
link.exe /OUT:"test_bin\gpr_thd_test.exe" /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 Debug\grpc_test_util.lib Debug\gpr.lib test_bin\thd_test.obj
link.exe /OUT:"test_bin\gpr_thd_test.exe" /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 Debug\gpr_test_util.lib Debug\gpr.lib test_bin\thd_test.obj
echo(
echo Running test gpr_thd_test
test_bin\gpr_thd_test.exe || echo TEST FAILED: gpr_thd_test && exit /b
@ -99,7 +99,7 @@ echo(
echo Building test gpr_time_test
cl.exe /c /I..\.. /I..\..\include /nologo /ZI /W3 /WX- /sdl /D WIN32 /D _LIB /D _USE_32BIT_TIME_T /D _UNICODE /D UNICODE /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /TC /analyze- /Fo:test_bin\ ..\..\test\core\support\time_test.c
link.exe /OUT:"test_bin\gpr_time_test.exe" /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 Debug\grpc_test_util.lib Debug\gpr.lib test_bin\time_test.obj
link.exe /OUT:"test_bin\gpr_time_test.exe" /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 Debug\gpr_test_util.lib Debug\gpr.lib test_bin\time_test.obj
echo(
echo Running test gpr_time_test
test_bin\gpr_time_test.exe || echo TEST FAILED: gpr_time_test && exit /b

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<IntDir>$(Configuration)\$(ProjectName)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<IntDir>$(Configuration)\$(ProjectName)\</IntDir>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="global.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="global.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\test\core\util\test_config.c">
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

@ -15,6 +15,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_unsecure", "grpc_unsec
{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr_test_util", "gpr_test_util.vcxproj", "{EAB0A629-17A9-44DB-B5FF-E91A721FE037}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_test_util", "grpc_test_util.vcxproj", "{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "third_party\zlibvc.vcxproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}"
@ -39,6 +41,10 @@ Global
{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Debug|Win32.Build.0 = Debug|Win32
{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release|Win32.ActiveCfg = Release|Win32
{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release|Win32.Build.0 = Release|Win32
{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Debug|Win32.ActiveCfg = Debug|Win32
{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Debug|Win32.Build.0 = Debug|Win32
{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Release|Win32.ActiveCfg = Release|Win32
{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Release|Win32.Build.0 = Release|Win32
{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug|Win32.ActiveCfg = Debug|Win32
{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug|Win32.Build.0 = Debug|Win32
{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Release|Win32.ActiveCfg = Release|Win32

@ -91,7 +91,6 @@
<ClInclude Include="..\..\src\core\tsi\ssl_transport_security.h" />
<ClInclude Include="..\..\src\core\tsi\transport_security.h" />
<ClInclude Include="..\..\src\core\tsi\transport_security_interface.h" />
<ClInclude Include="..\..\src\core\tsi\transport_security_test_lib.h" />
<ClInclude Include="..\..\src\core\channel\census_filter.h" />
<ClInclude Include="..\..\src\core\channel\channel_args.h" />
<ClInclude Include="..\..\src\core\channel\channel_stack.h" />
@ -175,6 +174,8 @@
</ClCompile>
<ClCompile Include="..\..\src\core\security\credentials.c">
</ClCompile>
<ClCompile Include="..\..\src\core\security\factories.c">
</ClCompile>
<ClCompile Include="..\..\src\core\security\google_root_certs.c">
</ClCompile>
<ClCompile Include="..\..\src\core\security\json_token.c">

@ -91,13 +91,11 @@
</ClCompile>
<ClCompile Include="..\..\test\core\util\grpc_profiler.c">
</ClCompile>
<ClCompile Include="..\..\test\core\util\parse_hexstring.c">
</ClCompile>
<ClCompile Include="..\..\test\core\util\port_posix.c">
</ClCompile>
<ClCompile Include="..\..\test\core\util\slice_splitter.c">
<ClCompile Include="..\..\test\core\util\parse_hexstring.c">
</ClCompile>
<ClCompile Include="..\..\test\core\util\test_config.c">
<ClCompile Include="..\..\test\core\util\slice_splitter.c">
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

@ -91,7 +91,6 @@
<ClInclude Include="..\..\src\core\tsi\ssl_transport_security.h" />
<ClInclude Include="..\..\src\core\tsi\transport_security.h" />
<ClInclude Include="..\..\src\core\tsi\transport_security_interface.h" />
<ClInclude Include="..\..\src\core\tsi\transport_security_test_lib.h" />
<ClInclude Include="..\..\src\core\channel\census_filter.h" />
<ClInclude Include="..\..\src\core\channel\channel_args.h" />
<ClInclude Include="..\..\src\core\channel\channel_stack.h" />
@ -175,6 +174,8 @@
</ClCompile>
<ClCompile Include="..\..\src\core\security\credentials.c">
</ClCompile>
<ClCompile Include="..\..\src\core\security\factories.c">
</ClCompile>
<ClCompile Include="..\..\src\core\security\google_root_certs.c">
</ClCompile>
<ClCompile Include="..\..\src\core\security\json_token.c">

Loading…
Cancel
Save