void checkChain(IOBuf* buf, boost::mt19937& gen) { IOBuf *current = buf; do { checkBuf(current->data(), current->length(), gen); current = current->next(); } while (current != buf); }
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()); }
/** * 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 }