blob: 3f1032ab8ad3c3dc2aeecd0587bd9a5931350fa1 [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02003 * Copyright 2015 gRPC authors.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08004 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02005 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08008 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02009 * http://www.apache.org/licenses/LICENSE-2.0
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080010 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +020011 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080016 *
17 */
18
Craig Tiller9a4dddd2016-03-25 17:08:13 -070019#ifndef GRPC_CORE_LIB_TRANSPORT_METADATA_H
20#define GRPC_CORE_LIB_TRANSPORT_METADATA_H
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080021
Craig Tiller7c70b6c2017-01-23 07:48:42 -080022#include <grpc/grpc.h>
Craig Tillerb37d53e2016-10-26 16:16:35 -070023#include <grpc/slice.h>
ctillerfb93d192014-12-15 10:40:05 -080024#include <grpc/support/useful.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080025
Craig Tiller87a7e1f2016-11-09 09:42:19 -080026#include "src/core/lib/iomgr/exec_ctx.h"
27
ncteisen4b584052017-06-08 16:44:38 -070028#ifndef NDEBUG
29extern grpc_tracer_flag grpc_trace_metadata;
30#endif
31
Mark D. Roth07cd9c92016-06-27 10:14:38 -070032#ifdef __cplusplus
33extern "C" {
34#endif
35
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080036/* This file provides a mechanism for tracking metadata through the grpc stack.
37 It's not intended for consumption outside of the library.
38
39 Metadata is tracked in the context of a grpc_mdctx. For the time being there
40 is one of these per-channel, avoiding cross channel interference with memory
41 use and lock contention.
42
43 The context tracks unique strings (grpc_mdstr) and pairs of strings
44 (grpc_mdelem). Any of these objects can be checked for equality by comparing
45 their pointers. These objects are reference counted.
46
47 grpc_mdelem can additionally store a (non-NULL) user data pointer. This
48 pointer is intended to be used to cache semantic meaning of a metadata
49 element. For example, an OAuth token may cache the credentials it represents
50 and the time at which it expires in the mdelem user data.
51
52 Combining this metadata cache and the hpack compression table allows us to
53 simply lookup complete preparsed objects quickly, incurring a few atomic
54 ops per metadata element on the fast path.
55
56 grpc_mdelem instances MAY live longer than their refcount implies, and are
57 garbage collected periodically, meaning cached data can easily outlive a
Craig Tiller70b080d2015-11-19 08:04:48 -080058 single request.
59
60 STATIC METADATA: in static_metadata.h we declare a set of static metadata.
61 These mdelems and mdstrs are available via pre-declared code generated macros
62 and are available to code anywhere between grpc_init() and grpc_shutdown().
63 They are not refcounted, but can be passed to _ref and _unref functions
64 declared here - in which case those functions are effectively no-ops. */
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080065
66/* Forward declarations */
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080067typedef struct grpc_mdelem grpc_mdelem;
68
Craig Tiller7c70b6c2017-01-23 07:48:42 -080069/* if changing this, make identical changes in:
70 - interned_metadata, allocated_metadata in metadata.c
71 - grpc_metadata in grpc_types.h */
72typedef struct grpc_mdelem_data {
73 const grpc_slice key;
74 const grpc_slice value;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080075 /* there is a private part to this in metadata.c */
Craig Tiller7c70b6c2017-01-23 07:48:42 -080076} grpc_mdelem_data;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080077
Craig Tiller7c70b6c2017-01-23 07:48:42 -080078/* GRPC_MDELEM_STORAGE_* enum values that can be treated as interned always have
79 this bit set in their integer value */
80#define GRPC_MDELEM_STORAGE_INTERNED_BIT 1
81
82typedef enum {
83 /* memory pointed to by grpc_mdelem::payload is owned by an external system */
84 GRPC_MDELEM_STORAGE_EXTERNAL = 0,
85 /* memory pointed to by grpc_mdelem::payload is interned by the metadata
86 system */
87 GRPC_MDELEM_STORAGE_INTERNED = GRPC_MDELEM_STORAGE_INTERNED_BIT,
88 /* memory pointed to by grpc_mdelem::payload is allocated by the metadata
89 system */
90 GRPC_MDELEM_STORAGE_ALLOCATED = 2,
91 /* memory is in the static metadata table */
92 GRPC_MDELEM_STORAGE_STATIC = 2 | GRPC_MDELEM_STORAGE_INTERNED_BIT,
93} grpc_mdelem_data_storage;
94
Craig Tiller5e01e2a2017-01-20 18:11:52 -080095struct grpc_mdelem {
Craig Tiller7c70b6c2017-01-23 07:48:42 -080096 /* a grpc_mdelem_data* generally, with the two lower bits signalling memory
97 ownership as per grpc_mdelem_data_storage */
98 uintptr_t payload;
Craig Tiller5e01e2a2017-01-20 18:11:52 -080099};
Craig Tiller9ecadce2016-11-18 14:52:25 -0800100
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800101#define GRPC_MDELEM_DATA(md) \
102 ((grpc_mdelem_data *)((md).payload & ~(uintptr_t)3))
103#define GRPC_MDELEM_STORAGE(md) \
104 ((grpc_mdelem_data_storage)((md).payload & (uintptr_t)3))
Yash Tibrewald8b84a22017-09-25 13:38:03 -0700105#ifdef __cplusplus
106#define GRPC_MAKE_MDELEM(data, storage) \
107 (grpc_mdelem{((uintptr_t)(data)) | ((uintptr_t)storage)})
108#else
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800109#define GRPC_MAKE_MDELEM(data, storage) \
110 ((grpc_mdelem){((uintptr_t)(data)) | ((uintptr_t)storage)})
Yash Tibrewald8b84a22017-09-25 13:38:03 -0700111#endif
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800112#define GRPC_MDELEM_IS_INTERNED(md) \
113 ((grpc_mdelem_data_storage)((md).payload & \
114 (uintptr_t)GRPC_MDELEM_STORAGE_INTERNED_BIT))
Craig Tiller5e01e2a2017-01-20 18:11:52 -0800115
Julien Boeuf75c9b6f2015-05-29 13:12:12 -0700116/* Unrefs the slices. */
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800117grpc_mdelem grpc_mdelem_from_slices(grpc_exec_ctx *exec_ctx, grpc_slice key,
118 grpc_slice value);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800119
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800120/* Cheaply convert a grpc_metadata to a grpc_mdelem; may use the grpc_metadata
121 object as backing storage (so lifetimes should align) */
122grpc_mdelem grpc_mdelem_from_grpc_metadata(grpc_exec_ctx *exec_ctx,
123 grpc_metadata *metadata);
124
125/* Does not unref the slices; if a new non-interned mdelem is needed, allocates
126 one if compatible_external_backing_store is NULL, or uses
127 compatible_external_backing_store if it is non-NULL (in which case it's the
128 users responsibility to ensure that it outlives usage) */
129grpc_mdelem grpc_mdelem_create(
130 grpc_exec_ctx *exec_ctx, grpc_slice key, grpc_slice value,
131 grpc_mdelem_data *compatible_external_backing_store);
132
133bool grpc_mdelem_eq(grpc_mdelem a, grpc_mdelem b);
134
yang-gfd42ceb2017-10-10 16:55:13 -0700135size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem elem,
136 bool use_true_binary_metadata);
yang-gcb7a8022016-03-30 14:58:53 -0700137
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800138/* Mutator and accessor for grpc_mdelem user data. The destructor function
139 is used as a type tag and is checked during user_data fetch. */
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800140void *grpc_mdelem_get_user_data(grpc_mdelem md,
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800141 void (*if_destroy_func)(void *));
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800142void *grpc_mdelem_set_user_data(grpc_mdelem md, void (*destroy_func)(void *),
Craig Tiller738e6db2016-11-15 09:29:44 -0800143 void *user_data);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800144
ncteisen4b584052017-06-08 16:44:38 -0700145#ifndef NDEBUG
Craig Tiller1a65a232015-07-06 10:22:32 -0700146#define GRPC_MDELEM_REF(s) grpc_mdelem_ref((s), __FILE__, __LINE__)
Craig Tillera59c16c2016-10-31 07:25:01 -0700147#define GRPC_MDELEM_UNREF(exec_ctx, s) \
148 grpc_mdelem_unref((exec_ctx), (s), __FILE__, __LINE__)
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800149grpc_mdelem grpc_mdelem_ref(grpc_mdelem md, const char *file, int line);
150void grpc_mdelem_unref(grpc_exec_ctx *exec_ctx, grpc_mdelem md,
Craig Tillera59c16c2016-10-31 07:25:01 -0700151 const char *file, int line);
Craig Tiller1a65a232015-07-06 10:22:32 -0700152#else
Craig Tiller1a65a232015-07-06 10:22:32 -0700153#define GRPC_MDELEM_REF(s) grpc_mdelem_ref((s))
Craig Tillera59c16c2016-10-31 07:25:01 -0700154#define GRPC_MDELEM_UNREF(exec_ctx, s) grpc_mdelem_unref((exec_ctx), (s))
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800155grpc_mdelem grpc_mdelem_ref(grpc_mdelem md);
156void grpc_mdelem_unref(grpc_exec_ctx *exec_ctx, grpc_mdelem md);
Craig Tiller1a65a232015-07-06 10:22:32 -0700157#endif
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800158
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800159#define GRPC_MDKEY(md) (GRPC_MDELEM_DATA(md)->key)
160#define GRPC_MDVALUE(md) (GRPC_MDELEM_DATA(md)->value)
Craig Tiller0160de92016-11-18 08:46:46 -0800161
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800162#define GRPC_MDNULL GRPC_MAKE_MDELEM(NULL, GRPC_MDELEM_STORAGE_EXTERNAL)
163#define GRPC_MDISNULL(md) (GRPC_MDELEM_DATA(md) == NULL)
Craig Tiller0160de92016-11-18 08:46:46 -0800164
Mark D. Rothc2de4522016-04-29 10:25:27 -0700165/* We add 32 bytes of padding as per RFC-7540 section 6.5.2. */
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800166#define GRPC_MDELEM_LENGTH(e) \
167 (GRPC_SLICE_LENGTH(GRPC_MDKEY((e))) + GRPC_SLICE_LENGTH(GRPC_MDVALUE((e))) + \
168 32)
murgatroid99c3910ca2016-01-06 13:14:23 -0800169
ctillerfb93d192014-12-15 10:40:05 -0800170#define GRPC_MDSTR_KV_HASH(k_hash, v_hash) (GPR_ROTL((k_hash), 2) ^ (v_hash))
171
Craig Tiller0e72ede2015-11-19 07:48:53 -0800172void grpc_mdctx_global_init(void);
Craig Tillera59c16c2016-10-31 07:25:01 -0700173void grpc_mdctx_global_shutdown(grpc_exec_ctx *exec_ctx);
Craig Tiller0e72ede2015-11-19 07:48:53 -0800174
Mark D. Roth07cd9c92016-06-27 10:14:38 -0700175#ifdef __cplusplus
176}
177#endif
178
Craig Tiller9a4dddd2016-03-25 17:08:13 -0700179#endif /* GRPC_CORE_LIB_TRANSPORT_METADATA_H */