1 /* 2 * 3 * Copyright 2016 gRPC authors. 4 * 5 * 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 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * 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. 16 * 17 */ 18 19 #ifndef GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H 20 #define GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H 21 22 #include <grpc/support/port_platform.h> 23 24 #include <grpc/impl/codegen/grpc_types.h> 25 26 #include "src/core/lib/iomgr/closure.h" 27 #include "src/core/lib/iomgr/endpoint.h" 28 #include "src/core/lib/iomgr/exec_ctx.h" 29 #include "src/core/lib/iomgr/tcp_server.h" 30 31 /// Handshakers are used to perform initial handshakes on a connection 32 /// before the client sends the initial request. Some examples of what 33 /// a handshaker can be used for includes support for HTTP CONNECT on 34 /// the client side and various types of security initialization. 35 /// 36 /// In general, handshakers should be used via a handshake manager. 37 38 /// 39 /// grpc_handshaker 40 /// 41 42 typedef struct grpc_handshaker grpc_handshaker; 43 44 /// Arguments passed through handshakers and to the on_handshake_done callback. 45 /// 46 /// For handshakers, all members are input/output parameters; for 47 /// example, a handshaker may read from or write to \a endpoint and 48 /// then later replace it with a wrapped endpoint. Similarly, a 49 /// handshaker may modify \a args. 50 /// 51 /// A handshaker takes ownership of the members while a handshake is in 52 /// progress. Upon failure or shutdown of an in-progress handshaker, 53 /// the handshaker is responsible for destroying the members and setting 54 /// them to NULL before invoking the on_handshake_done callback. 55 /// 56 /// For the on_handshake_done callback, all members are input arguments, 57 /// which the callback takes ownership of. 58 typedef struct { 59 grpc_pollset_set* interested_parties; 60 grpc_endpoint* endpoint; 61 grpc_channel_args* args; 62 grpc_slice_buffer* read_buffer; 63 // A handshaker may set this to true before invoking on_handshake_done 64 // to indicate that subsequent handshakers should be skipped. 65 bool exit_early; 66 // User data passed through the handshake manager. Not used by 67 // individual handshakers. 68 void* user_data; 69 } grpc_handshaker_args; 70 71 typedef struct { 72 /// Destroys the handshaker. 73 void (*destroy)(grpc_handshaker* handshaker); 74 75 /// Shuts down the handshaker (e.g., to clean up when the operation is 76 /// aborted in the middle). 77 void (*shutdown)(grpc_handshaker* handshaker, grpc_error* why); 78 79 /// Performs handshaking, modifying \a args as needed (e.g., to 80 /// replace \a endpoint with a wrapped endpoint). 81 /// When finished, invokes \a on_handshake_done. 82 /// \a acceptor will be NULL for client-side handshakers. 83 void (*do_handshake)(grpc_handshaker* handshaker, 84 grpc_tcp_server_acceptor* acceptor, 85 grpc_closure* on_handshake_done, 86 grpc_handshaker_args* args); 87 88 /// The name of the handshaker, for debugging purposes. 89 const char* name; 90 } grpc_handshaker_vtable; 91 92 /// Base struct. To subclass, make this the first member of the 93 /// implementation struct. 94 struct grpc_handshaker { 95 const grpc_handshaker_vtable* vtable; 96 }; 97 98 /// Called by concrete implementations to initialize the base struct. 99 void grpc_handshaker_init(const grpc_handshaker_vtable* vtable, 100 grpc_handshaker* handshaker); 101 102 void grpc_handshaker_destroy(grpc_handshaker* handshaker); 103 void grpc_handshaker_shutdown(grpc_handshaker* handshaker, grpc_error* why); 104 void grpc_handshaker_do_handshake(grpc_handshaker* handshaker, 105 grpc_tcp_server_acceptor* acceptor, 106 grpc_closure* on_handshake_done, 107 grpc_handshaker_args* args); 108 const char* grpc_handshaker_name(grpc_handshaker* handshaker); 109 110 /// 111 /// grpc_handshake_manager 112 /// 113 114 typedef struct grpc_handshake_manager grpc_handshake_manager; 115 116 /// Creates a new handshake manager. Caller takes ownership. 117 grpc_handshake_manager* grpc_handshake_manager_create(); 118 119 /// Adds a handshaker to the handshake manager. 120 /// Takes ownership of \a handshaker. 121 void grpc_handshake_manager_add(grpc_handshake_manager* mgr, 122 grpc_handshaker* handshaker); 123 124 /// Destroys the handshake manager. 125 void grpc_handshake_manager_destroy(grpc_handshake_manager* mgr); 126 127 /// Shuts down the handshake manager (e.g., to clean up when the operation is 128 /// aborted in the middle). 129 /// The caller must still call grpc_handshake_manager_destroy() after 130 /// calling this function. 131 void grpc_handshake_manager_shutdown(grpc_handshake_manager* mgr, 132 grpc_error* why); 133 134 /// Invokes handshakers in the order they were added. 135 /// \a interested_parties may be non-nullptr to provide a pollset_set that 136 /// may be used during handshaking. Ownership is not taken. 137 /// Takes ownership of \a endpoint, and then passes that ownership to 138 /// the \a on_handshake_done callback. 139 /// Does NOT take ownership of \a channel_args. Instead, makes a copy before 140 /// invoking the first handshaker. 141 /// \a acceptor will be nullptr for client-side handshakers. 142 /// 143 /// When done, invokes \a on_handshake_done with a grpc_handshaker_args 144 /// object as its argument. If the callback is invoked with error != 145 /// GRPC_ERROR_NONE, then handshaking failed and the handshaker has done 146 /// the necessary clean-up. Otherwise, the callback takes ownership of 147 /// the arguments. 148 void grpc_handshake_manager_do_handshake( 149 grpc_handshake_manager* mgr, grpc_pollset_set* interested_parties, 150 grpc_endpoint* endpoint, const grpc_channel_args* channel_args, 151 grpc_millis deadline, grpc_tcp_server_acceptor* acceptor, 152 grpc_iomgr_cb_func on_handshake_done, void* user_data); 153 154 /// Add \a mgr to the server side list of all pending handshake managers, the 155 /// list starts with \a *head. 156 // Not thread-safe. Caller needs to synchronize. 157 void grpc_handshake_manager_pending_list_add(grpc_handshake_manager** head, 158 grpc_handshake_manager* mgr); 159 160 /// Remove \a mgr from the server side list of all pending handshake managers. 161 // Not thread-safe. Caller needs to synchronize. 162 void grpc_handshake_manager_pending_list_remove(grpc_handshake_manager** head, 163 grpc_handshake_manager* mgr); 164 165 /// Shutdown all pending handshake managers on the server side. 166 // Not thread-safe. Caller needs to synchronize. 167 void grpc_handshake_manager_pending_list_shutdown_all( 168 grpc_handshake_manager* head, grpc_error* why); 169 170 #endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H */ 171