Beispiel #1
0
void IOBuf::markExternallyShared() {
  IOBuf* current = this;
  do {
    current->markExternallySharedOne();
    current = current->next_;
  } while (current != this);
}
Beispiel #2
0
void checkChain(IOBuf* buf, boost::mt19937& gen) {
  IOBuf *current = buf;
  do {
    checkBuf(current->data(), current->length(), gen);
    current = current->next();
  } while (current != buf);
}
Beispiel #3
0
BENCHMARK(cloneIntoBenchmark, iters) {
  IOBuf buf(IOBuf::CREATE, 10);
  IOBuf copy;
  while (iters--) {
    buf.cloneInto(copy);
    folly::doNotOptimizeAway(copy.capacity());
  }
}
Beispiel #4
0
IOBuf IOBuf::cloneAsValue() const {
  auto tmp = cloneOneAsValue();

  for (IOBuf* current = next_; current != this; current = current->next_) {
    tmp.prependChain(current->cloneOne());
  }

  return tmp;
}
Beispiel #5
0
unique_ptr<IOBuf> IOBuf::clone() const {
  unique_ptr<IOBuf> newHead(cloneOne());

  for (IOBuf* current = next_; current != this; current = current->next_) {
    newHead->prependChain(current->cloneOne());
  }

  return newHead;
}
pair<void*,uint64_t>
IOBufQueue::preallocateSlow(uint64_t min, uint64_t newAllocationSize,
                            uint64_t max) {
  // Allocate a new buffer of the requested max size.
  unique_ptr<IOBuf> newBuf(IOBuf::create(std::max(min, newAllocationSize)));
  appendToChain(head_, std::move(newBuf), false);
  IOBuf* last = head_->prev();
  return make_pair(last->writableTail(),
                   std::min(max, last->tailroom()));
}
Beispiel #7
0
void IOBuf::cloneInto(IOBuf& other) const {
  IOBuf tmp;
  cloneOneInto(tmp);

  for (IOBuf* current = next_; current != this; current = current->next_) {
    tmp.prependChain(current->cloneOne());
  }

  other = std::move(tmp);
}
void IOBufQueue::clear() {
  if (!head_) {
    return;
  }
  IOBuf* buf = head_.get();
  do {
    buf->clear();
    buf = buf->next();
  } while (buf != head_.get());
  chainLength_ = 0;
}
Beispiel #9
0
void IOBuf::makeManagedChained() {
  assert(isChained());

  IOBuf* current = this;
  while (true) {
    current->makeManagedOne();
    current = current->next_;
    if (current == this) {
      break;
    }
  }
}
void
IOBufQueue::append(const void* buf, size_t len) {
  auto src = static_cast<const uint8_t*>(buf);
  while (len != 0) {
    if ((head_ == nullptr) || head_->prev()->isSharedOne() ||
        (head_->prev()->tailroom() == 0)) {
      appendToChain(head_,
          IOBuf::create(std::max(MIN_ALLOC_SIZE,
              std::min(len, MAX_ALLOC_SIZE))),
          false);
    }
    IOBuf* last = head_->prev();
    uint64_t copyLen = std::min(len, (size_t)last->tailroom());
    memcpy(last->writableTail(), src, copyLen);
    src += copyLen;
    last->append(copyLen);
    chainLength_ += copyLen;
    len -= copyLen;
  }
}
Beispiel #11
0
TEST(IOBuf, move) {
  // Default allocate an IOBuf on the stack
  IOBuf outerBuf;
  char data[] = "foobar";
  uint32_t length = sizeof(data);
  uint32_t actualCapacity{0};
  const void* ptr{nullptr};

  {
    // Create a small IOBuf on the stack.
    // Note that IOBufs created on the stack always use an external buffer.
    IOBuf b1(IOBuf::CREATE, 10);
    actualCapacity = b1.capacity();
    EXPECT_GE(actualCapacity, 10);
    EXPECT_EQ(0, b1.length());
    EXPECT_FALSE(b1.isShared());
    ptr = b1.data();
    ASSERT_TRUE(ptr != nullptr);
    memcpy(b1.writableTail(), data, length);
    b1.append(length);
    EXPECT_EQ(length, b1.length());

    // Use the move constructor
    IOBuf b2(std::move(b1));
    EXPECT_EQ(ptr, b2.data());
    EXPECT_EQ(length, b2.length());
    EXPECT_EQ(actualCapacity, b2.capacity());
    EXPECT_FALSE(b2.isShared());

    // Use the move assignment operator
    outerBuf = std::move(b2);
    // Close scope, destroying b1 and b2
    // (which are both be invalid now anyway after moving out of them)
  }

  EXPECT_EQ(ptr, outerBuf.data());
  EXPECT_EQ(length, outerBuf.length());
  EXPECT_EQ(actualCapacity, outerBuf.capacity());
  EXPECT_FALSE(outerBuf.isShared());
}
Beispiel #12
0
void IOBuf::unshareChained() {
  // unshareChained() should only be called if we are part of a chain of
  // multiple IOBufs.  The caller should have already verified this.
  assert(isChained());

  IOBuf* current = this;
  while (true) {
    if (current->isSharedOne()) {
      // we have to unshare
      break;
    }

    current = current->next_;
    if (current == this) {
      // None of the IOBufs in the chain are shared,
      // so return without doing anything
      return;
    }
  }

  // We have to unshare.  Let coalesceSlow() do the work.
  coalesceSlow();
}
Beispiel #13
0
IOBuf::IOBuf(const IOBuf& other) {
  *this = other.cloneAsValue();
}
/**
 * Some utility functions.
 */
unique_ptr<folly::IOBuf> KerberosSASLHandshakeUtils::wrapMessage(
  gss_ctx_id_t context,
  unique_ptr<folly::IOBuf>&& buf) {

#ifdef GSSAPI_EXT_H_
  uint64_t numElements = buf->countChainElements();

  // Allocate iov vector with header | data blocks ... | padding | trailer
  std::vector<gss_iov_buffer_desc> iov(numElements + 3);
  uint64_t headerIdx = 0;
  uint64_t paddingIdx = numElements + 1;
  uint64_t trailerIdx = numElements + 2;
  iov[headerIdx].type = GSS_IOV_BUFFER_TYPE_HEADER;

  uint64_t count = 1;
  IOBuf *current = buf.get();
  do {
    iov[count].type = GSS_IOV_BUFFER_TYPE_DATA;
    iov[count].buffer.value = (void *)current->writableData();
    iov[count].buffer.length = current->length();
    count++;
    current = current->next();
  } while (current != buf.get());

  iov[paddingIdx].type = GSS_IOV_BUFFER_TYPE_PADDING;
  iov[trailerIdx].type = GSS_IOV_BUFFER_TYPE_TRAILER;

  // Compute required header / padding / trailer lengths
  OM_uint32 maj_stat, min_stat;
  maj_stat = gss_wrap_iov_length(
    &min_stat,
    context,
    1,
    GSS_C_QOP_DEFAULT,
    nullptr,
    &iov[0],
    iov.size());
  if (maj_stat != GSS_S_COMPLETE) {
    KerberosSASLHandshakeUtils::throwGSSException(
      "Error constructing iov chain", maj_stat, min_stat);
  }

  // Allocate the additional buffers
  std::unique_ptr<IOBuf> header = IOBuf::create(
    iov[headerIdx].buffer.length);
  header->append(iov[headerIdx].buffer.length);
  std::unique_ptr<IOBuf> padding = IOBuf::create(
    iov[paddingIdx].buffer.length);
  padding->append(iov[paddingIdx].buffer.length);
  std::unique_ptr<IOBuf> trailer = IOBuf::create(
    iov[trailerIdx].buffer.length);
  trailer->append(iov[trailerIdx].buffer.length);
  iov[headerIdx].buffer.value = (void *)header->writableData();
  iov[paddingIdx].buffer.value = (void *)padding->writableData();
  iov[trailerIdx].buffer.value = (void *)trailer->writableData();

  // Link all the buffers in a chain
  header->prependChain(std::move(buf));
  header->prependChain(std::move(padding));
  header->prependChain(std::move(trailer));

  // Encrypt in place
  maj_stat = gss_wrap_iov(
    &min_stat,
    context,
    1, // conf and integrity requested
    GSS_C_QOP_DEFAULT,
    nullptr,
    &iov[0],
    iov.size()
  );
  if (maj_stat != GSS_S_COMPLETE) {
    KerberosSASLHandshakeUtils::throwGSSException(
      "Error wrapping message", maj_stat, min_stat);
  }

  return header;
#else
  // Don't bother with getting things working on an older platform.
  // Things should never reach this point anyway, because security will
  // be disabled at a higher level.
  throw TKerberosException(
    "Linking against older version of krb5 without support for security.");
  return std::move(buf);
#endif
}
Beispiel #15
0
IOBuf::IOBuf(const IOBuf& other) {
  other.cloneInto(*this);
}