Line data Source code
1 : #pragma once 2 : 3 : #include <memory> 4 : 5 : #include "envoy/buffer/buffer.h" 6 : #include "envoy/event/dispatcher.h" 7 : 8 : #include "source/common/common/c_smart_ptr.h" 9 : #include "source/extensions/transport_sockets/alts/alts_tsi_handshaker.h" 10 : #include "source/extensions/transport_sockets/alts/grpc_tsi.h" 11 : 12 : #include "absl/status/status.h" 13 : 14 : namespace Envoy { 15 : namespace Extensions { 16 : namespace TransportSockets { 17 : namespace Alts { 18 : 19 : /** 20 : * An interface to get callbacks from TsiHandshaker. TsiHandshaker will call this callbacks in the 21 : * thread which its dispatcher posts to. 22 : */ 23 : class TsiHandshakerCallbacks { 24 : public: 25 0 : virtual ~TsiHandshakerCallbacks() = default; 26 : 27 : struct NextResult { 28 : // A status of the result. 29 : absl::Status status_; 30 : 31 : // The buffer to be sent to the peer. 32 : Buffer::InstancePtr to_send_; 33 : 34 : // A pointer to AltsHandshakeResult. Owned by instance. 35 : std::unique_ptr<AltsHandshakeResult> result_; 36 : }; 37 : 38 : using NextResultPtr = std::unique_ptr<NextResult>; 39 : 40 : /** 41 : * Called when `next` is done, this may be called inline in `next` if the handshaker is not 42 : * asynchronous. 43 : * @param result a unique pointer to NextResult struct including the result returned by TSI. 44 : */ 45 : virtual void onNextDone(NextResultPtr&& result) PURE; 46 : }; 47 : 48 : /** 49 : * A C++ wrapper for tsi_handshaker interface. 50 : * For detail of tsi_handshaker, see 51 : * https://github.com/grpc/grpc/blob/v1.12.0/src/core/tsi/transport_security_interface.h#L236 52 : */ 53 : class TsiHandshaker final : public Event::DeferredDeletable { 54 : public: 55 : explicit TsiHandshaker(std::unique_ptr<AltsTsiHandshaker> handshaker, 56 : Event::Dispatcher& dispatcher); 57 : ~TsiHandshaker() override; 58 : 59 : /** 60 : * Conduct next step of handshake, see 61 : * https://github.com/grpc/grpc/blob/v1.12.0/src/core/tsi/transport_security_interface.h#L418 62 : * It is callers responsibility to not call this method again until the 63 : * TsiHandshakerCallbacks::onNextDone is called. 64 : * @param received the buffer received from peer. 65 : */ 66 : absl::Status next(Buffer::Instance& received); 67 : 68 : /** 69 : * Set handshaker callbacks. This must be called before calling next. 70 : * @param callbacks supplies the callback instance. 71 : */ 72 0 : void setHandshakerCallbacks(TsiHandshakerCallbacks& callbacks) { callbacks_ = &callbacks; } 73 : 74 : /** 75 : * Delete the handshaker when it is ready. This must be called after releasing from a smart 76 : * pointer. If there is no call in progress, this calls dispatcher_.deferredDelete(). If there is 77 : * a call in progress dispatcher_.deferredDelete happens after ongoing next call are processed. 78 : */ 79 : void deferredDelete(); 80 : 81 : private: 82 : static void onNextDone(absl::Status status, void* handshaker, const unsigned char* bytes_to_send, 83 : size_t bytes_to_send_size, 84 : std::unique_ptr<AltsHandshakeResult> handshake_result); 85 : 86 : std::unique_ptr<AltsTsiHandshaker> handshaker_; 87 : TsiHandshakerCallbacks* callbacks_{}; 88 : 89 : // This is set to true when there is an ongoing next call to handshaker, and set to false when 90 : // the callback posted to dispatcher_ by TsiHandshaker::onNextDone is executed. 91 : bool calling_{false}; 92 : 93 : // This will be set when deferredDelete is called. If there is an ongoing next call, 94 : // the handshaker will delete itself after the call is processed. 95 : bool delete_on_done_{false}; 96 : 97 : Event::Dispatcher& dispatcher_; 98 : }; 99 : 100 : using TsiHandshakerPtr = std::unique_ptr<TsiHandshaker>; 101 : 102 : } // namespace Alts 103 : } // namespace TransportSockets 104 : } // namespace Extensions 105 : } // namespace Envoy