mirror of https://github.com/grpc/grpc.git
commit
5b5c8071c6
671 changed files with 38998 additions and 10317 deletions
@ -0,0 +1,17 @@ |
||||
There are times when we make changes that include a temporary shim for |
||||
backward-compatibility (e.g., a macro or some other function to preserve |
||||
the original API) to avoid having to bump the major version number in |
||||
the next release. However, when we do eventually want to release a |
||||
feature that does change the API in a non-backward-compatible way, we |
||||
will wind up bumping the major version number anyway, at which point we |
||||
can take the opportunity to clean up any pending backward-compatibility |
||||
shims. |
||||
|
||||
This file lists all pending backward-compatibility changes that should |
||||
be cleaned up the next time we are going to bump the major version |
||||
number: |
||||
|
||||
- remove `GRPC_ARG_MAX_MESSAGE_LENGTH` channel arg from |
||||
`include/grpc/impl/codegen/grpc_types.h` (commit `af00d8b`) |
||||
- remove `ServerBuilder::SetMaxMessageSize()` method from |
||||
`include/grpc++/server_builder.h` (commit `6980362`) |
@ -0,0 +1,30 @@ |
||||
# HTTP to gRPC Status Code Mapping |
||||
|
||||
Since intermediaries are a common part of HTTP infrastructure some responses to |
||||
gRPC requests may be received that do not include the grpc-status header. In |
||||
some cases mapping error codes from an intermediary allows the gRPC client to |
||||
behave more appropriately to the error situation without overloading the |
||||
semantics of either error code. |
||||
|
||||
This table is to be used _only_ for clients that received a response that did |
||||
not include grpc-status. If grpc-status was provided, it _must_ be used. Servers |
||||
_must not_ use this table to determine an HTTP status code to use; the mappings |
||||
are neither symmetric nor 1-to-1. |
||||
|
||||
| HTTP Status Code | gRPC Status Code | |
||||
|----------------------------|--------------------| |
||||
| 400 Bad Request | INTERNAL | |
||||
| 401 Unauthorized | UNAUTHENTICATED | |
||||
| 403 Forbidden | PERMISSION\_DENIED | |
||||
| 404 Not Found | UNIMPLEMENTED | |
||||
| 429 Too Many Requests | UNAVAILABLE | |
||||
| 502 Bad Gateway | UNAVAILABLE | |
||||
| 503 Service Unavailable | UNAVAILABLE | |
||||
| 504 Gateway Timeout | UNAVAILABLE | |
||||
| _All other codes_ | UNKNOWN | |
||||
|
||||
Technically, 1xx should have the entire header skipped and a subsequent header |
||||
be read. See RFC 7540 §8.1. |
||||
|
||||
200 is UNKNOWN because there should be a grpc-status in case of truly OK |
||||
response. |
@ -0,0 +1,192 @@ |
||||
# gRPC Server Reflection Tutorial |
||||
|
||||
gRPC Server Reflection provides information about publicly-accessible gRPC |
||||
services on a server, and assists clients at runtime to construct RPC |
||||
requests and responses without precompiled service information. It is used by |
||||
gRPC CLI, which can be used to introspect server protos and send/receive test |
||||
RPCs. |
||||
|
||||
## Enable Server Reflection |
||||
|
||||
### Enable server reflection in C++ servers |
||||
|
||||
C++ Server Reflection is an add-on library, `libgrpc++_reflction`. To enable C++ |
||||
server reflection, you can link this library to your server binary. |
||||
|
||||
Some platforms (e.g. Ubuntu 11.10 onwards) only link in libraries that directly |
||||
contain symbols used by the application. On these platforms, LD flag |
||||
`--no-as-needed` is needed for for dynamic linking and `--whole-archive` is |
||||
needed for for static linking. |
||||
|
||||
This [Makefile](../examples/cpp/helloworld/Makefile#L37#L45) demonstrates |
||||
enabling c++ server reflection on Linux and MacOS. |
||||
|
||||
## Test services using Server Reflection |
||||
|
||||
After enabling Server Reflection in a server application, you can use gRPC CLI |
||||
to test its services. |
||||
|
||||
Instructions on how to use gRPC CLI can be found at |
||||
[command_line_tool.md](command_line_tool.md), or using `grpc_cli help` command. |
||||
|
||||
Here we use `examples/cpp/helloworld` as an example to show the use of gRPC |
||||
Server Reflection and gRPC CLI. First, we need to build gRPC CLI and setup an |
||||
example server with Server Reflection enabled. |
||||
|
||||
- Setup an example server |
||||
|
||||
Server Reflection has already been enabled in the |
||||
[Makefile](../examples/cpp/helloworld/Makefile) of the helloworld example. We |
||||
can simply make it and run the greeter_server. |
||||
|
||||
```sh |
||||
$ make -C examples/cpp/helloworld |
||||
$ examples/cpp/helloworld/greeter_server & |
||||
``` |
||||
|
||||
- Build gRPC CLI |
||||
|
||||
```sh |
||||
make grpc_cli |
||||
cd bins/opt |
||||
``` |
||||
|
||||
gRPC CLI binary `grpc_cli` can be found at `bins/opt/` folder. This tool is |
||||
still new and does not have a `make install` target yet. |
||||
|
||||
### List services |
||||
|
||||
`grpc_cli ls` command lists services and methods exposed at a given port |
||||
|
||||
- List all the services exposed at a given port |
||||
|
||||
```sh |
||||
$ grpc_cli ls localhost:50051 |
||||
``` |
||||
|
||||
output: |
||||
```sh |
||||
helloworld.Greeter |
||||
grpc.reflection.v1alpha.ServerReflection |
||||
``` |
||||
|
||||
- List one service with details |
||||
|
||||
`grpc_cli ls` command inspects a service given its full name (in the format of |
||||
\<package\>.\<service\>). It can print information with a long listing format |
||||
when `-l` flag is set. This flag can be used to get more details about a |
||||
service. |
||||
|
||||
```sh |
||||
$ grpc_cli ls localhost:50051 helloworld.Greeter -l |
||||
``` |
||||
|
||||
output: |
||||
```sh |
||||
filename: helloworld.proto |
||||
package: helloworld; |
||||
service Greeter { |
||||
rpc SayHello(helloworld.HelloRequest) returns (helloworld.HelloReply) {} |
||||
} |
||||
|
||||
``` |
||||
|
||||
### List methods |
||||
|
||||
- List one method with details |
||||
|
||||
`grpc_cli ls` command also inspects a method given its full name (in the |
||||
format of \<package\>.\<service\>.\<method\>). |
||||
|
||||
```sh |
||||
$ grpc_cli ls localhost:50051 helloworld.Greeter.SayHello -l |
||||
``` |
||||
|
||||
output: |
||||
```sh |
||||
rpc SayHello(helloworld.HelloRequest) returns (helloworld.HelloReply) {} |
||||
``` |
||||
|
||||
### Inspect message types |
||||
|
||||
We can use`grpc_cli type` command to inspect request/response types given the |
||||
full name of the type (in the format of \<package\>.\<type\>). |
||||
|
||||
- Get information about the request type |
||||
|
||||
```sh |
||||
$ grpc_cli type localhost:50051 helloworld.HelloRequest |
||||
``` |
||||
|
||||
output: |
||||
```sh |
||||
message HelloRequest { |
||||
optional string name = 1; |
||||
} |
||||
``` |
||||
|
||||
### Call a remote method |
||||
|
||||
We can send RPCs to a server and get responses using `grpc_cli call` command. |
||||
|
||||
- Call a unary method |
||||
|
||||
```sh |
||||
$ grpc_cli call localhost:50051 SayHello "name: 'gRPC CLI'" |
||||
``` |
||||
|
||||
output: |
||||
```sh |
||||
message: "Hello gRPC CLI" |
||||
``` |
||||
|
||||
## Use Server Reflection in a C++ client |
||||
|
||||
Server Reflection can be used by clients to get information about gRPC services |
||||
at runtime. We've provided a descriptor database called |
||||
[grpc::ProtoReflectionDescriptorDatabase](../test/cpp/util/proto_reflection_descriptor_database.h) |
||||
which implements the |
||||
[google::protobuf::DescriptorDatabase](https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.descriptor_database#DescriptorDatabase) |
||||
interface. It manages the communication between clients and reflection services |
||||
and the storage of received information. Clients can use it as using a local |
||||
descriptor database. |
||||
|
||||
- To use Server Reflection with grpc::ProtoReflectionDescriptorDatabase, first |
||||
initialize an instance with a grpc::Channel. |
||||
|
||||
```c++ |
||||
std::shared_ptr<grpc::Channel> channel = |
||||
grpc::CreateChannel(server_address, server_cred); |
||||
grpc::ProtoReflectionDescriptorDatabase reflection_db(channel); |
||||
``` |
||||
|
||||
- Then use this instance to feed a |
||||
[google::protobuf::DescriptorPool](https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.descriptor#DescriptorPool). |
||||
|
||||
```c++ |
||||
google::protobuf::DescriptorPool desc_pool(&reflection_db); |
||||
``` |
||||
|
||||
- Example usage of this descriptor pool |
||||
|
||||
* Get Service/method descriptors. |
||||
|
||||
```c++ |
||||
const google::protobuf::ServiceDescriptor* service_desc = |
||||
desc_pool->FindServiceByName("helloworld.Greeter"); |
||||
const google::protobuf::MethodDescriptor* method_desc = |
||||
desc_pool->FindMethodByName("helloworld.Greeter.SayHello"); |
||||
``` |
||||
|
||||
* Get message type descriptors. |
||||
|
||||
```c++ |
||||
const google::protobuf::Descriptor* request_desc = |
||||
desc_pool->FindMessageTypeByName("helloworld.HelloRequest"); |
||||
``` |
||||
|
||||
* Feed [google::protobuf::DynamicMessageFactory](https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.dynamic_message#DynamicMessageFactory). |
||||
|
||||
```c++ |
||||
google::protobuf::DynamicMessageFactory(&desc_pool); |
||||
``` |
@ -0,0 +1,4 @@ |
||||
The roots.pem file is periodically generated from: |
||||
https://hg.mozilla.org/mozilla-central/raw-file/tip/security/nss/lib/ckfw/builtins/certdata.txt |
||||
using |
||||
https://github.com/agl/extract-nss-root-certs |
@ -1,122 +0,0 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015-2016, Google Inc. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following disclaimer |
||||
* in the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_IMPL_CODEGEN_BYTE_BUFFER_H |
||||
#define GRPC_IMPL_CODEGEN_BYTE_BUFFER_H |
||||
|
||||
#include <grpc/impl/codegen/compression_types.h> |
||||
#include <grpc/impl/codegen/slice_buffer.h> |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
typedef enum { |
||||
GRPC_BB_RAW |
||||
/* Future types may include GRPC_BB_PROTOBUF, etc. */ |
||||
} grpc_byte_buffer_type; |
||||
|
||||
struct grpc_byte_buffer { |
||||
void *reserved; |
||||
grpc_byte_buffer_type type; |
||||
union { |
||||
struct { |
||||
void *reserved[8]; |
||||
} reserved; |
||||
struct { |
||||
grpc_compression_algorithm compression; |
||||
gpr_slice_buffer slice_buffer; |
||||
} raw; |
||||
} data; |
||||
}; |
||||
typedef struct grpc_byte_buffer grpc_byte_buffer; |
||||
|
||||
/** Returns a RAW byte buffer instance over the given slices (up to \a nslices).
|
||||
* |
||||
* Increases the reference count for all \a slices processed. The user is |
||||
* responsible for invoking grpc_byte_buffer_destroy on the returned instance.*/ |
||||
GRPCAPI grpc_byte_buffer *grpc_raw_byte_buffer_create(gpr_slice *slices, |
||||
size_t nslices); |
||||
|
||||
/** Returns a *compressed* RAW byte buffer instance over the given slices (up to
|
||||
* \a nslices). The \a compression argument defines the compression algorithm |
||||
* used to generate the data in \a slices. |
||||
* |
||||
* Increases the reference count for all \a slices processed. The user is |
||||
* responsible for invoking grpc_byte_buffer_destroy on the returned instance.*/ |
||||
GRPCAPI grpc_byte_buffer *grpc_raw_compressed_byte_buffer_create( |
||||
gpr_slice *slices, size_t nslices, grpc_compression_algorithm compression); |
||||
|
||||
/** Copies input byte buffer \a bb.
|
||||
* |
||||
* Increases the reference count of all the source slices. The user is |
||||
* responsible for calling grpc_byte_buffer_destroy over the returned copy. */ |
||||
GRPCAPI grpc_byte_buffer *grpc_byte_buffer_copy(grpc_byte_buffer *bb); |
||||
|
||||
/** Returns the size of the given byte buffer, in bytes. */ |
||||
GRPCAPI size_t grpc_byte_buffer_length(grpc_byte_buffer *bb); |
||||
|
||||
/** Destroys \a byte_buffer deallocating all its memory. */ |
||||
GRPCAPI void grpc_byte_buffer_destroy(grpc_byte_buffer *byte_buffer); |
||||
|
||||
/** Reader for byte buffers. Iterates over slices in the byte buffer */ |
||||
struct grpc_byte_buffer_reader; |
||||
typedef struct grpc_byte_buffer_reader grpc_byte_buffer_reader; |
||||
|
||||
/** Initialize \a reader to read over \a buffer.
|
||||
* Returns 1 upon success, 0 otherwise. */ |
||||
GRPCAPI int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader, |
||||
grpc_byte_buffer *buffer); |
||||
|
||||
/** Cleanup and destroy \a reader */ |
||||
GRPCAPI void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader); |
||||
|
||||
/** Updates \a slice with the next piece of data from from \a reader and returns
|
||||
* 1. Returns 0 at the end of the stream. Caller is responsible for calling |
||||
* gpr_slice_unref on the result. */ |
||||
GRPCAPI int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader *reader, |
||||
gpr_slice *slice); |
||||
|
||||
/** Merge all data from \a reader into single slice */ |
||||
GRPCAPI gpr_slice |
||||
grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader *reader); |
||||
|
||||
/** Returns a RAW byte buffer instance from the output of \a reader. */ |
||||
GRPCAPI grpc_byte_buffer *grpc_raw_byte_buffer_from_reader( |
||||
grpc_byte_buffer_reader *reader); |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* GRPC_IMPL_CODEGEN_BYTE_BUFFER_H */ |
@ -0,0 +1,140 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2016, Google Inc. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following disclaimer |
||||
* in the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_IMPL_CODEGEN_GPR_TYPES_H |
||||
#define GRPC_IMPL_CODEGEN_GPR_TYPES_H |
||||
|
||||
#include <grpc/impl/codegen/port_platform.h> |
||||
|
||||
#include <stddef.h> |
||||
#include <stdint.h> |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/* The clocks we support. */ |
||||
typedef enum { |
||||
/* Monotonic clock. Epoch undefined. Always moves forwards. */ |
||||
GPR_CLOCK_MONOTONIC = 0, |
||||
/* Realtime clock. May jump forwards or backwards. Settable by
|
||||
the system administrator. Has its epoch at 0:00:00 UTC 1 Jan 1970. */ |
||||
GPR_CLOCK_REALTIME, |
||||
/* CPU cycle time obtained by rdtsc instruction on x86 platforms. Epoch
|
||||
undefined. Degrades to GPR_CLOCK_REALTIME on other platforms. */ |
||||
GPR_CLOCK_PRECISE, |
||||
/* Unmeasurable clock type: no base, created by taking the difference
|
||||
between two times */ |
||||
GPR_TIMESPAN |
||||
} gpr_clock_type; |
||||
|
||||
/* Analogous to struct timespec. On some machines, absolute times may be in
|
||||
* local time. */ |
||||
typedef struct gpr_timespec { |
||||
int64_t tv_sec; |
||||
int32_t tv_nsec; |
||||
/** Against which clock was this time measured? (or GPR_TIMESPAN if
|
||||
this is a relative time meaure) */ |
||||
gpr_clock_type clock_type; |
||||
} gpr_timespec; |
||||
|
||||
/* Slice API
|
||||
|
||||
A slice represents a contiguous reference counted array of bytes. |
||||
It is cheap to take references to a slice, and it is cheap to create a |
||||
slice pointing to a subset of another slice. |
||||
|
||||
The data-structure for slices is exposed here to allow non-gpr code to |
||||
build slices from whatever data they have available. |
||||
|
||||
When defining interfaces that handle slices, care should be taken to define |
||||
reference ownership semantics (who should call unref?) and mutability |
||||
constraints (is the callee allowed to modify the slice?) */ |
||||
|
||||
/* Reference count container for gpr_slice. Contains function pointers to
|
||||
increment and decrement reference counts. Implementations should cleanup |
||||
when the reference count drops to zero. |
||||
Typically client code should not touch this, and use gpr_slice_malloc, |
||||
gpr_slice_new, or gpr_slice_new_with_len instead. */ |
||||
typedef struct gpr_slice_refcount { |
||||
void (*ref)(void *); |
||||
void (*unref)(void *); |
||||
} gpr_slice_refcount; |
||||
|
||||
#define GPR_SLICE_INLINED_SIZE (sizeof(size_t) + sizeof(uint8_t *) - 1) |
||||
|
||||
/* A gpr_slice s, if initialized, represents the byte range
|
||||
s.bytes[0..s.length-1]. |
||||
|
||||
It can have an associated ref count which has a destruction routine to be run |
||||
when the ref count reaches zero (see gpr_slice_new() and grp_slice_unref()). |
||||
Multiple gpr_slice values may share a ref count. |
||||
|
||||
If the slice does not have a refcount, it represents an inlined small piece |
||||
of data that is copied by value. */ |
||||
typedef struct gpr_slice { |
||||
struct gpr_slice_refcount *refcount; |
||||
union { |
||||
struct { |
||||
uint8_t *bytes; |
||||
size_t length; |
||||
} refcounted; |
||||
struct { |
||||
uint8_t length; |
||||
uint8_t bytes[GPR_SLICE_INLINED_SIZE]; |
||||
} inlined; |
||||
} data; |
||||
} gpr_slice; |
||||
|
||||
#define GRPC_SLICE_BUFFER_INLINE_ELEMENTS 8 |
||||
|
||||
/* Represents an expandable array of slices, to be interpreted as a
|
||||
single item. */ |
||||
typedef struct { |
||||
/* slices in the array */ |
||||
gpr_slice *slices; |
||||
/* the number of slices in the array */ |
||||
size_t count; |
||||
/* the number of slices allocated in the array */ |
||||
size_t capacity; |
||||
/* the combined length of all slices in the array */ |
||||
size_t length; |
||||
/* inlined elements to avoid allocations */ |
||||
gpr_slice inlined[GRPC_SLICE_BUFFER_INLINE_ELEMENTS]; |
||||
} gpr_slice_buffer; |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* GRPC_IMPL_CODEGEN_GPR_TYPES_H */ |
@ -1,118 +0,0 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015, Google Inc. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following disclaimer |
||||
* in the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_IMPL_CODEGEN_LOG_H |
||||
#define GRPC_IMPL_CODEGEN_LOG_H |
||||
|
||||
#include <inttypes.h> |
||||
#include <stdarg.h> |
||||
#include <stdlib.h> /* for abort() */ |
||||
|
||||
#include <grpc/impl/codegen/port_platform.h> |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/* GPR log API.
|
||||
|
||||
Usage (within grpc): |
||||
|
||||
int argument1 = 3; |
||||
char* argument2 = "hello"; |
||||
gpr_log(GPR_DEBUG, "format string %d", argument1); |
||||
gpr_log(GPR_INFO, "hello world"); |
||||
gpr_log(GPR_ERROR, "%d %s!!", argument1, argument2); */ |
||||
|
||||
/* The severity of a log message - use the #defines below when calling into
|
||||
gpr_log to additionally supply file and line data */ |
||||
typedef enum gpr_log_severity { |
||||
GPR_LOG_SEVERITY_DEBUG, |
||||
GPR_LOG_SEVERITY_INFO, |
||||
GPR_LOG_SEVERITY_ERROR |
||||
} gpr_log_severity; |
||||
|
||||
#define GPR_LOG_VERBOSITY_UNSET -1 |
||||
|
||||
/* Returns a string representation of the log severity */ |
||||
const char *gpr_log_severity_string(gpr_log_severity severity); |
||||
|
||||
/* Macros to build log contexts at various severity levels */ |
||||
#define GPR_DEBUG __FILE__, __LINE__, GPR_LOG_SEVERITY_DEBUG |
||||
#define GPR_INFO __FILE__, __LINE__, GPR_LOG_SEVERITY_INFO |
||||
#define GPR_ERROR __FILE__, __LINE__, GPR_LOG_SEVERITY_ERROR |
||||
|
||||
/* Log a message. It's advised to use GPR_xxx above to generate the context
|
||||
* for each message */ |
||||
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, |
||||
const char *format, ...) GPRC_PRINT_FORMAT_CHECK(4, 5); |
||||
|
||||
GPRAPI void gpr_log_message(const char *file, int line, |
||||
gpr_log_severity severity, const char *message); |
||||
|
||||
/* Set global log verbosity */ |
||||
GPRAPI void gpr_set_log_verbosity(gpr_log_severity min_severity_to_print); |
||||
|
||||
GPRAPI void gpr_log_verbosity_init(); |
||||
|
||||
/* Log overrides: applications can use this API to intercept logging calls
|
||||
and use their own implementations */ |
||||
|
||||
typedef struct { |
||||
const char *file; |
||||
int line; |
||||
gpr_log_severity severity; |
||||
const char *message; |
||||
} gpr_log_func_args; |
||||
|
||||
typedef void (*gpr_log_func)(gpr_log_func_args *args); |
||||
GPRAPI void gpr_set_log_function(gpr_log_func func); |
||||
|
||||
/* abort() the process if x is zero, having written a line to the log.
|
||||
|
||||
Intended for internal invariants. If the error can be recovered from, |
||||
without the possibility of corruption, or might best be reflected via |
||||
an exception in a higher-level language, consider returning error code. */ |
||||
#define GPR_ASSERT(x) \ |
||||
do { \
|
||||
if (!(x)) { \
|
||||
gpr_log(GPR_ERROR, "assertion failed: %s", #x); \
|
||||
abort(); \
|
||||
} \
|
||||
} while (0) |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* GRPC_IMPL_CODEGEN_LOG_H */ |
@ -1,104 +0,0 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015, Google Inc. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following disclaimer |
||||
* in the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_IMPL_CODEGEN_SLICE_BUFFER_H |
||||
#define GRPC_IMPL_CODEGEN_SLICE_BUFFER_H |
||||
|
||||
#include <grpc/impl/codegen/slice.h> |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
#define GRPC_SLICE_BUFFER_INLINE_ELEMENTS 8 |
||||
|
||||
/* Represents an expandable array of slices, to be interpreted as a
|
||||
single item. */ |
||||
typedef struct { |
||||
/* slices in the array */ |
||||
gpr_slice *slices; |
||||
/* the number of slices in the array */ |
||||
size_t count; |
||||
/* the number of slices allocated in the array */ |
||||
size_t capacity; |
||||
/* the combined length of all slices in the array */ |
||||
size_t length; |
||||
/* inlined elements to avoid allocations */ |
||||
gpr_slice inlined[GRPC_SLICE_BUFFER_INLINE_ELEMENTS]; |
||||
} gpr_slice_buffer; |
||||
|
||||
/* initialize a slice buffer */ |
||||
GPRAPI void gpr_slice_buffer_init(gpr_slice_buffer *sb); |
||||
/* destroy a slice buffer - unrefs any held elements */ |
||||
GPRAPI void gpr_slice_buffer_destroy(gpr_slice_buffer *sb); |
||||
/* Add an element to a slice buffer - takes ownership of the slice.
|
||||
This function is allowed to concatenate the passed in slice to the end of |
||||
some other slice if desired by the slice buffer. */ |
||||
GPRAPI void gpr_slice_buffer_add(gpr_slice_buffer *sb, gpr_slice slice); |
||||
/* add an element to a slice buffer - takes ownership of the slice and returns
|
||||
the index of the slice. |
||||
Guarantees that the slice will not be concatenated at the end of another |
||||
slice (i.e. the data for this slice will begin at the first byte of the |
||||
slice at the returned index in sb->slices) |
||||
The implementation MAY decide to concatenate data at the end of a small |
||||
slice added in this fashion. */ |
||||
GPRAPI size_t gpr_slice_buffer_add_indexed(gpr_slice_buffer *sb, |
||||
gpr_slice slice); |
||||
GPRAPI void gpr_slice_buffer_addn(gpr_slice_buffer *sb, gpr_slice *slices, |
||||
size_t n); |
||||
/* add a very small (less than 8 bytes) amount of data to the end of a slice
|
||||
buffer: returns a pointer into which to add the data */ |
||||
GPRAPI uint8_t *gpr_slice_buffer_tiny_add(gpr_slice_buffer *sb, size_t len); |
||||
/* pop the last buffer, but don't unref it */ |
||||
GPRAPI void gpr_slice_buffer_pop(gpr_slice_buffer *sb); |
||||
/* clear a slice buffer, unref all elements */ |
||||
GPRAPI void gpr_slice_buffer_reset_and_unref(gpr_slice_buffer *sb); |
||||
/* swap the contents of two slice buffers */ |
||||
GPRAPI void gpr_slice_buffer_swap(gpr_slice_buffer *a, gpr_slice_buffer *b); |
||||
/* move all of the elements of src into dst */ |
||||
GPRAPI void gpr_slice_buffer_move_into(gpr_slice_buffer *src, |
||||
gpr_slice_buffer *dst); |
||||
/* remove n bytes from the end of a slice buffer */ |
||||
GPRAPI void gpr_slice_buffer_trim_end(gpr_slice_buffer *src, size_t n, |
||||
gpr_slice_buffer *garbage); |
||||
/* move the first n bytes of src into dst */ |
||||
GPRAPI void gpr_slice_buffer_move_first(gpr_slice_buffer *src, size_t n, |
||||
gpr_slice_buffer *dst); |
||||
/* take the first slice in the slice buffer */ |
||||
GPRAPI gpr_slice gpr_slice_buffer_take_first(gpr_slice_buffer *src); |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* GRPC_IMPL_CODEGEN_SLICE_BUFFER_H */ |
@ -1,130 +0,0 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015, Google Inc. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following disclaimer |
||||
* in the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_IMPL_CODEGEN_TIME_H |
||||
#define GRPC_IMPL_CODEGEN_TIME_H |
||||
/* Time support.
|
||||
We use gpr_timespec, which is analogous to struct timespec. On some |
||||
machines, absolute times may be in local time. */ |
||||
|
||||
#include <grpc/impl/codegen/port_platform.h> |
||||
#include <stddef.h> |
||||
#include <time.h> |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/* The clocks we support. */ |
||||
typedef enum { |
||||
/* Monotonic clock. Epoch undefined. Always moves forwards. */ |
||||
GPR_CLOCK_MONOTONIC = 0, |
||||
/* Realtime clock. May jump forwards or backwards. Settable by
|
||||
the system administrator. Has its epoch at 0:00:00 UTC 1 Jan 1970. */ |
||||
GPR_CLOCK_REALTIME, |
||||
/* CPU cycle time obtained by rdtsc instruction on x86 platforms. Epoch
|
||||
undefined. Degrades to GPR_CLOCK_REALTIME on other platforms. */ |
||||
GPR_CLOCK_PRECISE, |
||||
/* Unmeasurable clock type: no base, created by taking the difference
|
||||
between two times */ |
||||
GPR_TIMESPAN |
||||
} gpr_clock_type; |
||||
|
||||
typedef struct gpr_timespec { |
||||
int64_t tv_sec; |
||||
int32_t tv_nsec; |
||||
/** Against which clock was this time measured? (or GPR_TIMESPAN if
|
||||
this is a relative time meaure) */ |
||||
gpr_clock_type clock_type; |
||||
} gpr_timespec; |
||||
|
||||
/* Time constants. */ |
||||
GPRAPI gpr_timespec |
||||
gpr_time_0(gpr_clock_type type); /* The zero time interval. */ |
||||
GPRAPI gpr_timespec gpr_inf_future(gpr_clock_type type); /* The far future */ |
||||
GPRAPI gpr_timespec gpr_inf_past(gpr_clock_type type); /* The far past. */ |
||||
|
||||
#define GPR_MS_PER_SEC 1000 |
||||
#define GPR_US_PER_SEC 1000000 |
||||
#define GPR_NS_PER_SEC 1000000000 |
||||
#define GPR_NS_PER_MS 1000000 |
||||
#define GPR_NS_PER_US 1000 |
||||
#define GPR_US_PER_MS 1000 |
||||
|
||||
/* initialize time subsystem */ |
||||
GPRAPI void gpr_time_init(void); |
||||
|
||||
/* Return the current time measured from the given clocks epoch. */ |
||||
GPRAPI gpr_timespec gpr_now(gpr_clock_type clock); |
||||
|
||||
/* Convert a timespec from one clock to another */ |
||||
GPRAPI gpr_timespec gpr_convert_clock_type(gpr_timespec t, |
||||
gpr_clock_type target_clock); |
||||
|
||||
/* Return -ve, 0, or +ve according to whether a < b, a == b, or a > b
|
||||
respectively. */ |
||||
GPRAPI int gpr_time_cmp(gpr_timespec a, gpr_timespec b); |
||||
|
||||
GPRAPI gpr_timespec gpr_time_max(gpr_timespec a, gpr_timespec b); |
||||
GPRAPI gpr_timespec gpr_time_min(gpr_timespec a, gpr_timespec b); |
||||
|
||||
/* Add and subtract times. Calculations saturate at infinities. */ |
||||
GPRAPI gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b); |
||||
GPRAPI gpr_timespec gpr_time_sub(gpr_timespec a, gpr_timespec b); |
||||
|
||||
/* Return a timespec representing a given number of time units. INT64_MIN is
|
||||
interpreted as gpr_inf_past, and INT64_MAX as gpr_inf_future. */ |
||||
GPRAPI gpr_timespec gpr_time_from_micros(int64_t x, gpr_clock_type clock_type); |
||||
GPRAPI gpr_timespec gpr_time_from_nanos(int64_t x, gpr_clock_type clock_type); |
||||
GPRAPI gpr_timespec gpr_time_from_millis(int64_t x, gpr_clock_type clock_type); |
||||
GPRAPI gpr_timespec gpr_time_from_seconds(int64_t x, gpr_clock_type clock_type); |
||||
GPRAPI gpr_timespec gpr_time_from_minutes(int64_t x, gpr_clock_type clock_type); |
||||
GPRAPI gpr_timespec gpr_time_from_hours(int64_t x, gpr_clock_type clock_type); |
||||
|
||||
GPRAPI int32_t gpr_time_to_millis(gpr_timespec timespec); |
||||
|
||||
/* Return 1 if two times are equal or within threshold of each other,
|
||||
0 otherwise */ |
||||
GPRAPI int gpr_time_similar(gpr_timespec a, gpr_timespec b, |
||||
gpr_timespec threshold); |
||||
|
||||
/* Sleep until at least 'until' - an absolute timeout */ |
||||
GPRAPI void gpr_sleep_until(gpr_timespec until); |
||||
|
||||
GPRAPI double gpr_timespec_to_micros(gpr_timespec t); |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* GRPC_IMPL_CODEGEN_TIME_H */ |
@ -0,0 +1,86 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2016, 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/ext/census/trace_context.h" |
||||
|
||||
#include <grpc/census.h> |
||||
#include <grpc/support/log.h> |
||||
#include <stdbool.h> |
||||
|
||||
#include "third_party/nanopb/pb_decode.h" |
||||
#include "third_party/nanopb/pb_encode.h" |
||||
|
||||
// This function assumes the TraceContext is valid.
|
||||
size_t encode_trace_context(google_trace_TraceContext *ctxt, uint8_t *buffer, |
||||
const size_t buf_size) { |
||||
// Create a stream that will write to our buffer.
|
||||
pb_ostream_t stream = pb_ostream_from_buffer(buffer, buf_size); |
||||
|
||||
// encode message
|
||||
bool status = pb_encode(&stream, google_trace_TraceContext_fields, ctxt); |
||||
|
||||
if (!status) { |
||||
gpr_log(GPR_DEBUG, "TraceContext encoding failed: %s", |
||||
PB_GET_ERROR(&stream)); |
||||
return 0; |
||||
} |
||||
|
||||
return stream.bytes_written; |
||||
} |
||||
|
||||
bool decode_trace_context(google_trace_TraceContext *ctxt, uint8_t *buffer, |
||||
const size_t nbytes) { |
||||
// Create a stream that reads nbytes from the buffer.
|
||||
pb_istream_t stream = pb_istream_from_buffer(buffer, nbytes); |
||||
|
||||
// decode message
|
||||
bool status = pb_decode(&stream, google_trace_TraceContext_fields, ctxt); |
||||
|
||||
if (!status) { |
||||
gpr_log(GPR_DEBUG, "TraceContext decoding failed: %s", |
||||
PB_GET_ERROR(&stream)); |
||||
return false; |
||||
} |
||||
|
||||
// check fields
|
||||
if (!ctxt->has_trace_id) { |
||||
gpr_log(GPR_DEBUG, "Invalid TraceContext: missing trace_id"); |
||||
return false; |
||||
} |
||||
if (!ctxt->has_span_id) { |
||||
gpr_log(GPR_DEBUG, "Invalid TraceContext: missing span_id"); |
||||
return false; |
||||
} |
||||
|
||||
return true; |
||||
} |
@ -0,0 +1,68 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2016, 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. |
||||
* |
||||
*/ |
||||
|
||||
/* Functions for manipulating trace contexts as defined in
|
||||
src/proto/census/trace.proto */ |
||||
#ifndef GRPC_CORE_EXT_CENSUS_TRACE_CONTEXT_H |
||||
#define GRPC_CORE_EXT_CENSUS_TRACE_CONTEXT_H |
||||
|
||||
#include "src/core/ext/census/gen/trace_context.pb.h" |
||||
|
||||
/* Maximum number of bytes required to encode a TraceContext (31)
|
||||
1 byte for trace_id field |
||||
1 byte for trace_id length |
||||
1 byte for trace_id.hi field |
||||
8 bytes for trace_id.hi (uint64_t) |
||||
1 byte for trace_id.lo field |
||||
8 bytes for trace_id.lo (uint64_t) |
||||
1 byte for span_id field |
||||
8 bytes for span_id (uint64_t) |
||||
1 byte for is_sampled field |
||||
1 byte for is_sampled (bool) */ |
||||
#define TRACE_MAX_CONTEXT_SIZE 31 |
||||
|
||||
/* Encode a trace context (ctxt) into proto format to the buffer provided. The
|
||||
size of buffer must be at least TRACE_MAX_CONTEXT_SIZE. On success, returns the |
||||
number of bytes successfully encoded into buffer. On failure, returns 0. */ |
||||
size_t encode_trace_context(google_trace_TraceContext *ctxt, uint8_t *buffer, |
||||
const size_t buf_size); |
||||
|
||||
/* Decode a proto-encoded TraceContext from the provided buffer into the
|
||||
TraceContext structure (ctxt). The function expects to be supplied the number |
||||
of bytes to be read from buffer (nbytes). This function will also validate that |
||||
the TraceContext has a span_id and a trace_id, and will return false if either |
||||
of these do not exist. On success, returns true and false otherwise. */ |
||||
bool decode_trace_context(google_trace_TraceContext *ctxt, uint8_t *buffer, |
||||
const size_t nbytes); |
||||
|
||||
#endif |
@ -0,0 +1,275 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2016, 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/ext/client_config/http_connect_handshaker.h" |
||||
|
||||
#include <string.h> |
||||
|
||||
#include <grpc/support/alloc.h> |
||||
#include <grpc/support/log.h> |
||||
#include <grpc/support/slice_buffer.h> |
||||
#include <grpc/support/string_util.h> |
||||
|
||||
#include "src/core/ext/client_config/uri_parser.h" |
||||
#include "src/core/lib/http/format_request.h" |
||||
#include "src/core/lib/http/parser.h" |
||||
#include "src/core/lib/iomgr/timer.h" |
||||
#include "src/core/lib/support/env.h" |
||||
|
||||
typedef struct http_connect_handshaker { |
||||
// Base class. Must be first.
|
||||
grpc_handshaker base; |
||||
|
||||
char* proxy_server; |
||||
char* server_name; |
||||
|
||||
// State saved while performing the handshake.
|
||||
grpc_endpoint* endpoint; |
||||
grpc_channel_args* args; |
||||
grpc_handshaker_done_cb cb; |
||||
void* user_data; |
||||
|
||||
// Objects for processing the HTTP CONNECT request and response.
|
||||
gpr_slice_buffer write_buffer; |
||||
gpr_slice_buffer* read_buffer; // Ownership passes through this object.
|
||||
grpc_closure request_done_closure; |
||||
grpc_closure response_read_closure; |
||||
grpc_http_parser http_parser; |
||||
grpc_http_response http_response; |
||||
grpc_timer timeout_timer; |
||||
|
||||
gpr_refcount refcount; |
||||
} http_connect_handshaker; |
||||
|
||||
// Unref and clean up handshaker.
|
||||
static void http_connect_handshaker_unref(http_connect_handshaker* handshaker) { |
||||
if (gpr_unref(&handshaker->refcount)) { |
||||
gpr_free(handshaker->proxy_server); |
||||
gpr_free(handshaker->server_name); |
||||
gpr_slice_buffer_destroy(&handshaker->write_buffer); |
||||
grpc_http_parser_destroy(&handshaker->http_parser); |
||||
grpc_http_response_destroy(&handshaker->http_response); |
||||
gpr_free(handshaker); |
||||
} |
||||
} |
||||
|
||||
// Callback invoked when deadline is exceeded.
|
||||
static void on_timeout(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) { |
||||
http_connect_handshaker* handshaker = arg; |
||||
if (error == GRPC_ERROR_NONE) { // Timer fired, rather than being cancelled.
|
||||
grpc_endpoint_shutdown(exec_ctx, handshaker->endpoint); |
||||
} |
||||
http_connect_handshaker_unref(handshaker); |
||||
} |
||||
|
||||
// Callback invoked when finished writing HTTP CONNECT request.
|
||||
static void on_write_done(grpc_exec_ctx* exec_ctx, void* arg, |
||||
grpc_error* error) { |
||||
http_connect_handshaker* handshaker = arg; |
||||
if (error != GRPC_ERROR_NONE) { |
||||
// If the write failed, invoke the callback immediately with the error.
|
||||
handshaker->cb(exec_ctx, handshaker->endpoint, handshaker->args, |
||||
handshaker->read_buffer, handshaker->user_data, |
||||
GRPC_ERROR_REF(error)); |
||||
} else { |
||||
// Otherwise, read the response.
|
||||
grpc_endpoint_read(exec_ctx, handshaker->endpoint, handshaker->read_buffer, |
||||
&handshaker->response_read_closure); |
||||
} |
||||
} |
||||
|
||||
// Callback invoked for reading HTTP CONNECT response.
|
||||
static void on_read_done(grpc_exec_ctx* exec_ctx, void* arg, |
||||
grpc_error* error) { |
||||
http_connect_handshaker* handshaker = arg; |
||||
if (error != GRPC_ERROR_NONE) { |
||||
GRPC_ERROR_REF(error); // Take ref to pass to the handshake-done callback.
|
||||
goto done; |
||||
} |
||||
// Add buffer to parser.
|
||||
for (size_t i = 0; i < handshaker->read_buffer->count; ++i) { |
||||
if (GPR_SLICE_LENGTH(handshaker->read_buffer->slices[i]) > 0) { |
||||
size_t body_start_offset = 0; |
||||
error = grpc_http_parser_parse(&handshaker->http_parser, |
||||
handshaker->read_buffer->slices[i], |
||||
&body_start_offset); |
||||
if (error != GRPC_ERROR_NONE) goto done; |
||||
if (handshaker->http_parser.state == GRPC_HTTP_BODY) { |
||||
// We've gotten back a successul response, so stop the timeout timer.
|
||||
grpc_timer_cancel(exec_ctx, &handshaker->timeout_timer); |
||||
// Remove the data we've already read from the read buffer,
|
||||
// leaving only the leftover bytes (if any).
|
||||
gpr_slice_buffer tmp_buffer; |
||||
gpr_slice_buffer_init(&tmp_buffer); |
||||
if (body_start_offset < |
||||
GPR_SLICE_LENGTH(handshaker->read_buffer->slices[i])) { |
||||
gpr_slice_buffer_add( |
||||
&tmp_buffer, |
||||
gpr_slice_split_tail(&handshaker->read_buffer->slices[i], |
||||
body_start_offset)); |
||||
} |
||||
gpr_slice_buffer_addn(&tmp_buffer, |
||||
&handshaker->read_buffer->slices[i + 1], |
||||
handshaker->read_buffer->count - i - 1); |
||||
gpr_slice_buffer_swap(handshaker->read_buffer, &tmp_buffer); |
||||
gpr_slice_buffer_destroy(&tmp_buffer); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
// If we're not done reading the response, read more data.
|
||||
// TODO(roth): In practice, I suspect that the response to a CONNECT
|
||||
// request will never include a body, in which case this check is
|
||||
// sufficient. However, the language of RFC-2817 doesn't explicitly
|
||||
// forbid the response from including a body. If there is a body,
|
||||
// it's possible that we might have parsed part but not all of the
|
||||
// body, in which case this check will cause us to fail to parse the
|
||||
// remainder of the body. If that ever becomes an issue, we may
|
||||
// need to fix the HTTP parser to understand when the body is
|
||||
// complete (e.g., handling chunked transfer encoding or looking
|
||||
// at the Content-Length: header).
|
||||
if (handshaker->http_parser.state != GRPC_HTTP_BODY) { |
||||
gpr_slice_buffer_reset_and_unref(handshaker->read_buffer); |
||||
grpc_endpoint_read(exec_ctx, handshaker->endpoint, handshaker->read_buffer, |
||||
&handshaker->response_read_closure); |
||||
return; |
||||
} |
||||
// Make sure we got a 2xx response.
|
||||
if (handshaker->http_response.status < 200 || |
||||
handshaker->http_response.status >= 300) { |
||||
char* msg; |
||||
gpr_asprintf(&msg, "HTTP proxy returned response code %d", |
||||
handshaker->http_response.status); |
||||
error = GRPC_ERROR_CREATE(msg); |
||||
gpr_free(msg); |
||||
} |
||||
done: |
||||
// Invoke handshake-done callback.
|
||||
handshaker->cb(exec_ctx, handshaker->endpoint, handshaker->args, |
||||
handshaker->read_buffer, handshaker->user_data, error); |
||||
} |
||||
|
||||
//
|
||||
// Public handshaker methods
|
||||
//
|
||||
|
||||
static void http_connect_handshaker_destroy(grpc_exec_ctx* exec_ctx, |
||||
grpc_handshaker* handshaker_in) { |
||||
http_connect_handshaker* handshaker = (http_connect_handshaker*)handshaker_in; |
||||
http_connect_handshaker_unref(handshaker); |
||||
} |
||||
|
||||
static void http_connect_handshaker_shutdown(grpc_exec_ctx* exec_ctx, |
||||
grpc_handshaker* handshaker) {} |
||||
|
||||
static void http_connect_handshaker_do_handshake( |
||||
grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker_in, |
||||
grpc_endpoint* endpoint, grpc_channel_args* args, |
||||
gpr_slice_buffer* read_buffer, gpr_timespec deadline, |
||||
grpc_tcp_server_acceptor* acceptor, grpc_handshaker_done_cb cb, |
||||
void* user_data) { |
||||
http_connect_handshaker* handshaker = (http_connect_handshaker*)handshaker_in; |
||||
// Save state in the handshaker object.
|
||||
handshaker->endpoint = endpoint; |
||||
handshaker->args = args; |
||||
handshaker->cb = cb; |
||||
handshaker->user_data = user_data; |
||||
handshaker->read_buffer = read_buffer; |
||||
// Send HTTP CONNECT request.
|
||||
gpr_log(GPR_INFO, "Connecting to server %s via HTTP proxy %s", |
||||
handshaker->server_name, handshaker->proxy_server); |
||||
grpc_httpcli_request request; |
||||
memset(&request, 0, sizeof(request)); |
||||
request.host = handshaker->proxy_server; |
||||
request.http.method = "CONNECT"; |
||||
request.http.path = handshaker->server_name; |
||||
request.handshaker = &grpc_httpcli_plaintext; |
||||
gpr_slice request_slice = grpc_httpcli_format_connect_request(&request); |
||||
gpr_slice_buffer_add(&handshaker->write_buffer, request_slice); |
||||
grpc_endpoint_write(exec_ctx, endpoint, &handshaker->write_buffer, |
||||
&handshaker->request_done_closure); |
||||
// Set timeout timer. The timer gets a reference to the handshaker.
|
||||
gpr_ref(&handshaker->refcount); |
||||
grpc_timer_init(exec_ctx, &handshaker->timeout_timer, |
||||
gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC), |
||||
on_timeout, handshaker, gpr_now(GPR_CLOCK_MONOTONIC)); |
||||
} |
||||
|
||||
static const struct grpc_handshaker_vtable http_connect_handshaker_vtable = { |
||||
http_connect_handshaker_destroy, http_connect_handshaker_shutdown, |
||||
http_connect_handshaker_do_handshake}; |
||||
|
||||
grpc_handshaker* grpc_http_connect_handshaker_create(const char* proxy_server, |
||||
const char* server_name) { |
||||
GPR_ASSERT(proxy_server != NULL); |
||||
GPR_ASSERT(server_name != NULL); |
||||
http_connect_handshaker* handshaker = |
||||
gpr_malloc(sizeof(http_connect_handshaker)); |
||||
memset(handshaker, 0, sizeof(*handshaker)); |
||||
grpc_handshaker_init(&http_connect_handshaker_vtable, &handshaker->base); |
||||
handshaker->proxy_server = gpr_strdup(proxy_server); |
||||
handshaker->server_name = gpr_strdup(server_name); |
||||
gpr_slice_buffer_init(&handshaker->write_buffer); |
||||
grpc_closure_init(&handshaker->request_done_closure, on_write_done, |
||||
handshaker); |
||||
grpc_closure_init(&handshaker->response_read_closure, on_read_done, |
||||
handshaker); |
||||
grpc_http_parser_init(&handshaker->http_parser, GRPC_HTTP_RESPONSE, |
||||
&handshaker->http_response); |
||||
gpr_ref_init(&handshaker->refcount, 1); |
||||
return &handshaker->base; |
||||
} |
||||
|
||||
char* grpc_get_http_proxy_server() { |
||||
char* uri_str = gpr_getenv("http_proxy"); |
||||
if (uri_str == NULL) return NULL; |
||||
grpc_uri* uri = grpc_uri_parse(uri_str, false /* suppress_errors */); |
||||
char* proxy_name = NULL; |
||||
if (uri == NULL || uri->authority == NULL) { |
||||
gpr_log(GPR_ERROR, "cannot parse value of 'http_proxy' env var"); |
||||
goto done; |
||||
} |
||||
if (strcmp(uri->scheme, "http") != 0) { |
||||
gpr_log(GPR_ERROR, "'%s' scheme not supported in proxy URI", uri->scheme); |
||||
goto done; |
||||
} |
||||
if (strchr(uri->authority, '@') != NULL) { |
||||
gpr_log(GPR_ERROR, "userinfo not supported in proxy URI"); |
||||
goto done; |
||||
} |
||||
proxy_name = gpr_strdup(uri->authority); |
||||
done: |
||||
gpr_free(uri_str); |
||||
grpc_uri_destroy(uri); |
||||
return proxy_name; |
||||
} |
@ -0,0 +1,47 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2016, Google Inc. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following disclaimer |
||||
* in the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_CORE_EXT_CLIENT_CONFIG_HTTP_CONNECT_HANDSHAKER_H |
||||
#define GRPC_CORE_EXT_CLIENT_CONFIG_HTTP_CONNECT_HANDSHAKER_H |
||||
|
||||
#include "src/core/lib/channel/handshaker.h" |
||||
|
||||
/// Does NOT take ownership of \a proxy_server or \a server_name.
|
||||
grpc_handshaker* grpc_http_connect_handshaker_create(const char* proxy_server, |
||||
const char* server_name); |
||||
|
||||
/// Returns the name of the proxy to use, or NULL if no proxy is configured.
|
||||
/// Caller takes ownership of result.
|
||||
char* grpc_get_http_proxy_server(); |
||||
|
||||
#endif /* GRPC_CORE_EXT_CLIENT_CONFIG_HTTP_CONNECT_HANDSHAKER_H */ |
@ -1,75 +1,94 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015, Google Inc. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following disclaimer |
||||
* in the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
//
|
||||
// Copyright 2015, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#include "src/core/ext/client_config/resolver_result.h" |
||||
|
||||
#include <string.h> |
||||
|
||||
#include <grpc/support/alloc.h> |
||||
#include <grpc/support/string_util.h> |
||||
|
||||
#include "src/core/lib/channel/channel_args.h" |
||||
|
||||
struct grpc_resolver_result { |
||||
gpr_refcount refs; |
||||
grpc_lb_policy *lb_policy; |
||||
char* server_name; |
||||
grpc_lb_addresses* addresses; |
||||
char* lb_policy_name; |
||||
grpc_channel_args* lb_policy_args; |
||||
}; |
||||
|
||||
grpc_resolver_result *grpc_resolver_result_create() { |
||||
grpc_resolver_result *c = gpr_malloc(sizeof(*c)); |
||||
memset(c, 0, sizeof(*c)); |
||||
gpr_ref_init(&c->refs, 1); |
||||
return c; |
||||
grpc_resolver_result* grpc_resolver_result_create( |
||||
const char* server_name, grpc_lb_addresses* addresses, |
||||
const char* lb_policy_name, grpc_channel_args* lb_policy_args) { |
||||
grpc_resolver_result* result = gpr_malloc(sizeof(*result)); |
||||
memset(result, 0, sizeof(*result)); |
||||
gpr_ref_init(&result->refs, 1); |
||||
result->server_name = gpr_strdup(server_name); |
||||
result->addresses = addresses; |
||||
result->lb_policy_name = gpr_strdup(lb_policy_name); |
||||
result->lb_policy_args = lb_policy_args; |
||||
return result; |
||||
} |
||||
|
||||
void grpc_resolver_result_ref(grpc_resolver_result *c) { gpr_ref(&c->refs); } |
||||
void grpc_resolver_result_ref(grpc_resolver_result* result) { |
||||
gpr_ref(&result->refs); |
||||
} |
||||
|
||||
void grpc_resolver_result_unref(grpc_exec_ctx *exec_ctx, |
||||
grpc_resolver_result *c) { |
||||
if (gpr_unref(&c->refs)) { |
||||
if (c->lb_policy != NULL) { |
||||
GRPC_LB_POLICY_UNREF(exec_ctx, c->lb_policy, "resolver_result"); |
||||
} |
||||
gpr_free(c); |
||||
void grpc_resolver_result_unref(grpc_exec_ctx* exec_ctx, |
||||
grpc_resolver_result* result) { |
||||
if (gpr_unref(&result->refs)) { |
||||
gpr_free(result->server_name); |
||||
grpc_lb_addresses_destroy(result->addresses, NULL /* user_data_destroy */); |
||||
gpr_free(result->lb_policy_name); |
||||
grpc_channel_args_destroy(result->lb_policy_args); |
||||
gpr_free(result); |
||||
} |
||||
} |
||||
|
||||
void grpc_resolver_result_set_lb_policy(grpc_resolver_result *c, |
||||
grpc_lb_policy *lb_policy) { |
||||
GPR_ASSERT(c->lb_policy == NULL); |
||||
if (lb_policy) { |
||||
GRPC_LB_POLICY_REF(lb_policy, "resolver_result"); |
||||
} |
||||
c->lb_policy = lb_policy; |
||||
const char* grpc_resolver_result_get_server_name(grpc_resolver_result* result) { |
||||
return result->server_name; |
||||
} |
||||
|
||||
grpc_lb_addresses* grpc_resolver_result_get_addresses( |
||||
grpc_resolver_result* result) { |
||||
return result->addresses; |
||||
} |
||||
|
||||
const char* grpc_resolver_result_get_lb_policy_name( |
||||
grpc_resolver_result* result) { |
||||
return result->lb_policy_name; |
||||
} |
||||
|
||||
grpc_lb_policy *grpc_resolver_result_get_lb_policy(grpc_resolver_result *c) { |
||||
return c->lb_policy; |
||||
grpc_channel_args* grpc_resolver_result_get_lb_policy_args( |
||||
grpc_resolver_result* result) { |
||||
return result->lb_policy_args; |
||||
} |
||||
|
@ -1,52 +1,74 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015, Google Inc. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following disclaimer |
||||
* in the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
//
|
||||
// Copyright 2015, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#ifndef GRPC_CORE_EXT_CLIENT_CONFIG_RESOLVER_RESULT_H |
||||
#define GRPC_CORE_EXT_CLIENT_CONFIG_RESOLVER_RESULT_H |
||||
|
||||
#include "src/core/ext/client_config/lb_policy.h" |
||||
#include "src/core/ext/client_config/lb_policy_factory.h" |
||||
#include "src/core/lib/iomgr/resolve_address.h" |
||||
|
||||
/** Results reported from a grpc_resolver. */ |
||||
// TODO(roth, ctiller): In the long term, we are considering replacing
|
||||
// the resolver_result data structure with grpc_channel_args. The idea is
|
||||
// that the resolver will return a set of channel args that contains the
|
||||
// information that is currently in the resolver_result struct. For
|
||||
// example, there will be specific args indicating the set of addresses
|
||||
// and the name of the LB policy to instantiate. Note that if we did
|
||||
// this, we would probably want to change the data structure of
|
||||
// grpc_channel_args such to a hash table or AVL or some other data
|
||||
// structure that does not require linear search to find keys.
|
||||
|
||||
/// Results reported from a grpc_resolver.
|
||||
typedef struct grpc_resolver_result grpc_resolver_result; |
||||
|
||||
grpc_resolver_result *grpc_resolver_result_create(); |
||||
void grpc_resolver_result_ref(grpc_resolver_result *client_config); |
||||
void grpc_resolver_result_unref(grpc_exec_ctx *exec_ctx, |
||||
grpc_resolver_result *client_config); |
||||
/// Takes ownership of \a addresses and \a lb_policy_args.
|
||||
grpc_resolver_result* grpc_resolver_result_create( |
||||
const char* server_name, grpc_lb_addresses* addresses, |
||||
const char* lb_policy_name, grpc_channel_args* lb_policy_args); |
||||
void grpc_resolver_result_ref(grpc_resolver_result* result); |
||||
void grpc_resolver_result_unref(grpc_exec_ctx* exec_ctx, |
||||
grpc_resolver_result* result); |
||||
|
||||
/// Caller does NOT take ownership of result.
|
||||
const char* grpc_resolver_result_get_server_name(grpc_resolver_result* result); |
||||
|
||||
/// Caller does NOT take ownership of result.
|
||||
grpc_lb_addresses* grpc_resolver_result_get_addresses( |
||||
grpc_resolver_result* result); |
||||
|
||||
/// Caller does NOT take ownership of result.
|
||||
const char* grpc_resolver_result_get_lb_policy_name( |
||||
grpc_resolver_result* result); |
||||
|
||||
void grpc_resolver_result_set_lb_policy(grpc_resolver_result *client_config, |
||||
grpc_lb_policy *lb_policy); |
||||
grpc_lb_policy *grpc_resolver_result_get_lb_policy( |
||||
grpc_resolver_result *client_config); |
||||
/// Caller does NOT take ownership of result.
|
||||
grpc_channel_args* grpc_resolver_result_get_lb_policy_args( |
||||
grpc_resolver_result* result); |
||||
|
||||
#endif /* GRPC_CORE_EXT_CLIENT_CONFIG_RESOLVER_RESULT_H */ |
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue