1
#include "source/extensions/transport_sockets/alts/tsi_handshaker.h"
2

            
3
#include <cstddef>
4
#include <cstdint>
5
#include <memory>
6
#include <utility>
7

            
8
#include "envoy/buffer/buffer.h"
9
#include "envoy/event/dispatcher.h"
10

            
11
#include "source/common/buffer/buffer_impl.h"
12
#include "source/common/common/assert.h"
13
#include "source/extensions/transport_sockets/alts/alts_tsi_handshaker.h"
14

            
15
#include "absl/status/status.h"
16

            
17
namespace Envoy {
18
namespace Extensions {
19
namespace TransportSockets {
20
namespace Alts {
21

            
22
void TsiHandshaker::onNextDone(absl::Status status, void* handshaker,
23
                               const unsigned char* bytes_to_send, size_t bytes_to_send_size,
24
75
                               std::unique_ptr<AltsHandshakeResult> handshake_result) {
25
75
  TsiHandshaker* tsi_handshaker = static_cast<TsiHandshaker*>(handshaker);
26
75
  Buffer::InstancePtr to_send = std::make_unique<Buffer::OwnedImpl>();
27
75
  if (bytes_to_send_size > 0) {
28
53
    to_send->add(bytes_to_send, bytes_to_send_size);
29
53
  }
30

            
31
75
  auto next_result = new TsiHandshakerCallbacks::NextResult{status, std::move(to_send),
32
75
                                                            std::move(handshake_result)};
33

            
34
75
  tsi_handshaker->dispatcher_.post([tsi_handshaker, next_result]() {
35
75
    TsiHandshakerCallbacks::NextResultPtr next_result_ptr{next_result};
36

            
37
75
    ASSERT(tsi_handshaker->calling_);
38
75
    tsi_handshaker->calling_ = false;
39

            
40
75
    if (tsi_handshaker->delete_on_done_) {
41
2
      tsi_handshaker->deferredDelete();
42
2
      return;
43
2
    }
44
73
    tsi_handshaker->callbacks_->onNextDone(std::move(next_result_ptr));
45
73
  });
46
75
}
47

            
48
TsiHandshaker::TsiHandshaker(std::unique_ptr<AltsTsiHandshaker> handshaker,
49
                             Event::Dispatcher& dispatcher)
50
43
    : handshaker_(std::move(handshaker)), dispatcher_(dispatcher) {}
51

            
52
43
TsiHandshaker::~TsiHandshaker() { ASSERT(!calling_); }
53

            
54
75
absl::Status TsiHandshaker::next(Envoy::Buffer::Instance& received) {
55
75
  ASSERT(callbacks_);
56
75
  ASSERT(!calling_);
57
75
  calling_ = true;
58

            
59
75
  uint64_t received_size = received.length();
60
75
  absl::Status status = handshaker_->next(
61
75
      this, reinterpret_cast<const unsigned char*>(received.linearize(received_size)),
62
75
      received_size, onNextDone);
63

            
64
75
  received.drain(received_size);
65
75
  if (!status.ok()) {
66
7
    onNextDone(status, this, /*bytes_to_send=*/nullptr,
67
7
               /*bytes_to_send_size=*/0, /*handshake_result=*/nullptr);
68
7
  }
69
75
  return status;
70
75
}
71

            
72
41
void TsiHandshaker::deferredDelete() {
73
41
  if (calling_) {
74
2
    delete_on_done_ = true;
75
39
  } else {
76
39
    dispatcher_.deferredDelete(Event::DeferredDeletablePtr{this});
77
39
  }
78
41
}
79

            
80
} // namespace Alts
81
} // namespace TransportSockets
82
} // namespace Extensions
83
} // namespace Envoy