1
#include "source/common/network/raw_buffer_socket.h"
2

            
3
#include "source/common/api/os_sys_calls_impl.h"
4
#include "source/common/common/assert.h"
5
#include "source/common/common/empty_string.h"
6
#include "source/common/http/headers.h"
7

            
8
namespace Envoy {
9
namespace Network {
10

            
11
105834
void RawBufferSocket::setTransportSocketCallbacks(TransportSocketCallbacks& callbacks) {
12
105834
  ASSERT(!callbacks_);
13
105834
  callbacks_ = &callbacks;
14
105834
}
15

            
16
546837
IoResult RawBufferSocket::doRead(Buffer::Instance& buffer) {
17
546837
  PostIoAction action = PostIoAction::KeepOpen;
18
546837
  uint64_t bytes_read = 0;
19
546837
  bool end_stream = false;
20
546837
  absl::optional<Api::IoError::IoErrorCode> err = absl::nullopt;
21
1084818
  do {
22
1084818
    Api::IoCallUint64Result result = callbacks_->ioHandle().read(buffer, absl::nullopt);
23

            
24
1084818
    if (result.ok()) {
25
637050
      ENVOY_CONN_LOG(trace, "read returns: {}", callbacks_->connection(), result.return_value_);
26
637050
      if (result.return_value_ == 0) {
27
        // Remote close.
28
48760
        end_stream = true;
29
48760
        break;
30
48760
      }
31
588290
      bytes_read += result.return_value_;
32
588290
      if (callbacks_->shouldDrainReadBuffer()) {
33
50329
        callbacks_->setTransportSocketIsReadable();
34
50329
        break;
35
50329
      }
36
588460
    } else {
37
      // Remote error (might be no data).
38
447768
      ENVOY_CONN_LOG(trace, "read error: {}, code: {}", callbacks_->connection(),
39
447768
                     result.err_->getErrorDetails(), static_cast<int>(result.err_->getErrorCode()));
40
447768
      if (result.err_->getErrorCode() != Api::IoError::IoErrorCode::Again) {
41
421
        action = PostIoAction::Close;
42
421
        err = result.err_->getErrorCode();
43
421
      }
44
447768
      break;
45
447768
    }
46
1084818
  } while (true);
47

            
48
  return {action, bytes_read, end_stream, err};
49
546837
}
50

            
51
1248287
IoResult RawBufferSocket::doWrite(Buffer::Instance& buffer, bool end_stream) {
52
1248287
  PostIoAction action;
53
1248287
  uint64_t bytes_written = 0;
54
1248287
  absl::optional<Api::IoError::IoErrorCode> err = absl::nullopt;
55
1248287
  ASSERT(!shutdown_ || buffer.length() == 0);
56
1828778
  do {
57
1828778
    if (buffer.length() == 0) {
58
1245530
      if (end_stream && !shutdown_) {
59
        // Ignore the result. This can only fail if the connection failed. In that case, the
60
        // error will be detected on the next read, and dealt with appropriately.
61
2609
        callbacks_->ioHandle().shutdown(ENVOY_SHUT_WR);
62
2609
        shutdown_ = true;
63
2609
      }
64
1245530
      action = PostIoAction::KeepOpen;
65
1245530
      break;
66
1245530
    }
67
583248
    Api::IoCallUint64Result result = callbacks_->ioHandle().write(buffer);
68

            
69
583249
    if (result.ok()) {
70
580491
      ENVOY_CONN_LOG(trace, "write returns: {}", callbacks_->connection(), result.return_value_);
71
580491
      bytes_written += result.return_value_;
72
580436
    } else {
73
2758
      ENVOY_CONN_LOG(trace, "write error: {}, code: {}", callbacks_->connection(),
74
2758
                     result.err_->getErrorDetails(), static_cast<int>(result.err_->getErrorCode()));
75
2798
      if (result.err_->getErrorCode() == Api::IoError::IoErrorCode::Again) {
76
2473
        action = PostIoAction::KeepOpen;
77
2327
      } else {
78
325
        err = result.err_->getErrorCode();
79
325
        action = PostIoAction::Close;
80
325
      }
81
2758
      break;
82
2758
    }
83
583249
  } while (true);
84

            
85
  return {action, bytes_written, false, err};
86
1248287
}
87

            
88
458
std::string RawBufferSocket::protocol() const { return EMPTY_STRING; }
89
164157
absl::string_view RawBufferSocket::failureReason() const { return EMPTY_STRING; }
90

            
91
74505
void RawBufferSocket::onConnected() { callbacks_->raiseEvent(ConnectionEvent::Connected); }
92

            
93
TransportSocketPtr
94
RawBufferSocketFactory::createTransportSocket(TransportSocketOptionsConstSharedPtr,
95
30070
                                              Upstream::HostDescriptionConstSharedPtr) const {
96
30070
  return std::make_unique<RawBufferSocket>();
97
30070
}
98

            
99
53084
TransportSocketPtr RawBufferSocketFactory::createDownstreamTransportSocket() const {
100
53084
  return std::make_unique<RawBufferSocket>();
101
53084
}
102

            
103
1490
bool RawBufferSocketFactory::implementsSecureTransport() const { return false; }
104

            
105
} // namespace Network
106
} // namespace Envoy