Home | History | Annotate | Download | only in channel
      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