Skip to content

Commit

Permalink
Merge github.com:google/grpc
Browse files Browse the repository at this point in the history
  • Loading branch information
ctiller committed Jan 13, 2015
2 parents 225d31f + 6ad120e commit 9fef05c
Show file tree
Hide file tree
Showing 32 changed files with 1,021 additions and 1,819 deletions.
871 changes: 456 additions & 415 deletions Makefile

Large diffs are not rendered by default.

108 changes: 90 additions & 18 deletions build.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion include/grpc/grpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
2 changes: 0 additions & 2 deletions include/grpc/grpc_security.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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. */
Expand Down
28 changes: 28 additions & 0 deletions src/core/iomgr/sockaddr_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
6 changes: 6 additions & 0 deletions src/core/iomgr/sockaddr_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
5 changes: 4 additions & 1 deletion src/core/iomgr/tcp_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,17 @@ 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
creates one socket, but possibly two on systems which support IPv6,
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);

Expand Down
87 changes: 63 additions & 24 deletions src/core/iomgr/tcp_server_posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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 */
Expand Down Expand Up @@ -234,39 +242,64 @@ static void on_read(void *arg, int success) {
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);
Expand All @@ -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);
}
Expand All @@ -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) {
Expand Down
21 changes: 20 additions & 1 deletion src/core/security/credentials.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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; }

10 changes: 8 additions & 2 deletions src/core/security/credentials.h
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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 {
Expand All @@ -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__ */
80 changes: 80 additions & 0 deletions src/core/security/factories.c
Original file line number Diff line number Diff line change
@@ -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;
}
Loading

0 comments on commit 9fef05c

Please sign in to comment.