blob: 5d41df768ac43464779c6f2eeac9b9ea1685a82d [file] [log] [blame]
// Copyright (c) 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/third_party/quic/core/crypto/quic_tls_adapter.h"
#include "net/third_party/quic/platform/api/quic_logging.h"
#include "net/third_party/quic/platform/api/quic_string.h"
#include "net/third_party/quic/platform/api/quic_text_utils.h"
#include "starboard/client_porting/poem/string_poem.h"
#include "starboard/memory.h"
namespace quic {
const BIO_METHOD QuicTlsAdapter::kBIOMethod = {
0, // type
nullptr, // name
QuicTlsAdapter::BIOWriteWrapper,
QuicTlsAdapter::BIOReadWrapper,
nullptr, // puts
nullptr, // gets
QuicTlsAdapter::BIOCtrlWrapper,
nullptr, // create
nullptr, // destroy
nullptr, // callback_ctrl
};
// static
QuicTlsAdapter* QuicTlsAdapter::GetAdapter(BIO* bio) {
DCHECK_EQ(&kBIOMethod, bio->method);
QuicTlsAdapter* adapter = reinterpret_cast<QuicTlsAdapter*>(bio->ptr);
if (adapter)
DCHECK_EQ(bio, adapter->bio());
return adapter;
}
// static
int QuicTlsAdapter::BIOReadWrapper(BIO* bio, char* out, int len) {
QuicTlsAdapter* adapter = GetAdapter(bio);
if (!adapter)
return -1;
return adapter->Read(out, len);
}
// static
int QuicTlsAdapter::BIOWriteWrapper(BIO* bio, const char* in, int len) {
QuicTlsAdapter* adapter = GetAdapter(bio);
if (!adapter)
return -1;
return adapter->Write(in, len);
}
// static
// NOLINTNEXTLINE
long QuicTlsAdapter::BIOCtrlWrapper(BIO* bio, int cmd, long larg, void* parg) {
QuicTlsAdapter* adapter = GetAdapter(bio);
if (!adapter)
return 0;
switch (cmd) {
// The only control request sent by the TLS stack is from BIO_flush. Any
// other values of |cmd| would indicate some sort of programming error.
case BIO_CTRL_FLUSH:
adapter->Flush();
return 1;
}
QUIC_NOTREACHED();
return 0;
}
QuicTlsAdapter::QuicTlsAdapter(Visitor* visitor)
: visitor_(visitor), bio_(BIO_new(&kBIOMethod)) {
bio_->ptr = this;
bio_->init = 1;
}
QuicTlsAdapter::~QuicTlsAdapter() {}
QuicErrorCode QuicTlsAdapter::error() const {
// QuicTlsAdapter passes messages received from ProcessInput straight through
// to the TLS stack (via the BIO) and does not parse the messages at all.
// ProcessInput never fails, so there is never an error to provide.
return QUIC_NO_ERROR;
}
const QuicString& QuicTlsAdapter::error_detail() const {
return error_detail_;
}
bool QuicTlsAdapter::ProcessInput(QuicStringPiece input,
EncryptionLevel level) {
read_buffer_.append(input.data(), input.length());
visitor_->OnDataAvailableForBIO();
return true;
}
size_t QuicTlsAdapter::InputBytesRemaining() const {
return read_buffer_.length();
}
int QuicTlsAdapter::Read(char* out, int len) {
if (len < 0) {
return -1;
}
if (read_buffer_.empty()) {
BIO_set_retry_read(bio());
return -1;
}
if (len >= static_cast<int>(read_buffer_.length())) {
len = read_buffer_.length();
}
SbMemoryCopy(out, read_buffer_.data(), len);
read_buffer_.erase(0, len);
QUIC_LOG(INFO) << "BIO_read: reading " << len << " bytes:\n";
return len;
}
int QuicTlsAdapter::Write(const char* in, int len) {
if (len < 0) {
return -1;
}
QUIC_LOG(INFO) << "BIO_write: writing " << len << " bytes:\n";
write_buffer_.append(in, len);
return len;
}
void QuicTlsAdapter::Flush() {
QUIC_LOG(INFO) << "BIO_flush: flushing " << write_buffer_.size() << " bytes";
visitor_->OnDataReceivedFromBIO(write_buffer_);
write_buffer_.clear();
}
} // namespace quic