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
105600
void RawBufferSocket::setTransportSocketCallbacks(TransportSocketCallbacks& callbacks) {
12
105600
  ASSERT(!callbacks_);
13
105600
  callbacks_ = &callbacks;
14
105600
}
15

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

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

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

            
51
1258160
IoResult RawBufferSocket::doWrite(Buffer::Instance& buffer, bool end_stream) {
52
1258160
  PostIoAction action;
53
1258160
  uint64_t bytes_written = 0;
54
1258160
  absl::optional<Api::IoError::IoErrorCode> err = absl::nullopt;
55
1258160
  ASSERT(!shutdown_ || buffer.length() == 0);
56
1824650
  do {
57
1824650
    if (buffer.length() == 0) {
58
1255014
      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
2713
        callbacks_->ioHandle().shutdown(ENVOY_SHUT_WR);
62
2713
        shutdown_ = true;
63
2713
      }
64
1255014
      action = PostIoAction::KeepOpen;
65
1255014
      break;
66
1255014
    }
67
569636
    Api::IoCallUint64Result result = callbacks_->ioHandle().write(buffer);
68

            
69
569640
    if (result.ok()) {
70
566491
      ENVOY_CONN_LOG(trace, "write returns: {}", callbacks_->connection(), result.return_value_);
71
566491
      bytes_written += result.return_value_;
72
564839
    } else {
73
3149
      ENVOY_CONN_LOG(trace, "write error: {}, code: {}", callbacks_->connection(),
74
3149
                     result.err_->getErrorDetails(), static_cast<int>(result.err_->getErrorCode()));
75
3161
      if (result.err_->getErrorCode() == Api::IoError::IoErrorCode::Again) {
76
2720
        action = PostIoAction::KeepOpen;
77
2755
      } else {
78
441
        err = result.err_->getErrorCode();
79
441
        action = PostIoAction::Close;
80
441
      }
81
3149
      break;
82
3149
    }
83
569640
  } while (true);
84

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

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

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

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

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

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

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