More SSL stuff (still doesn't work :/).
This commit is contained in:
@@ -93,7 +93,7 @@ StreamError SSLStream::open(Stream& base, const std::string& hostname) noexcept
|
||||
externalBio_ = std::move(externalBio);
|
||||
base_ = &base;
|
||||
|
||||
if (const ossl::Error error = runIOLoop(&ossl::Ssl::connect); !error.isSuccess())
|
||||
if (const ossl::Error error = runIOLoop(&ossl::Ssl::connect, true); !error.isSuccess())
|
||||
{
|
||||
ssl_.free();
|
||||
externalBio.free();
|
||||
@@ -116,7 +116,7 @@ void SSLStream::close() noexcept
|
||||
{
|
||||
MIJIN_ASSERT(base_ != nullptr, "SSL stream is not open.");
|
||||
base_ = nullptr;
|
||||
(void) runIOLoop(&ossl::Ssl::shutdown);
|
||||
(void) runIOLoop(&ossl::Ssl::shutdown, true);
|
||||
ssl_.free();
|
||||
externalBio_.free();
|
||||
}
|
||||
@@ -131,7 +131,7 @@ StreamError SSLStream::writeRaw(std::span<const std::uint8_t> buffer)
|
||||
std::size_t bytesToWrite = buffer.size();
|
||||
while (bytesToWrite > 0)
|
||||
{
|
||||
const ossl::Result<int> result = runIOLoop(&ossl::Ssl::write, buffer.data() + buffer.size() - bytesToWrite,
|
||||
const ossl::Result<int> result = runIOLoop(&ossl::Ssl::write, true, buffer.data() + buffer.size() - bytesToWrite,
|
||||
static_cast<int>(bytesToWrite));
|
||||
if (result.isError())
|
||||
{
|
||||
@@ -156,15 +156,25 @@ StreamError SSLStream::readRaw(std::span<std::uint8_t> buffer, const mijin::Read
|
||||
return StreamError::SUCCESS;
|
||||
}
|
||||
|
||||
if (const StreamError error = baseToBio(); error != StreamError::SUCCESS)
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
if (!options.partial && options.noBlock && static_cast<std::size_t>(ssl_.pending()) < buffer.size())
|
||||
{
|
||||
return StreamError::WOULD_BLOCK;
|
||||
}
|
||||
|
||||
std::size_t bytesToRead = buffer.size();
|
||||
if (options.partial)
|
||||
{
|
||||
bytesToRead = std::min<std::size_t>(bytesToRead, ssl_.pending());
|
||||
}
|
||||
while (bytesToRead > 0)
|
||||
{
|
||||
if (const StreamError error = baseToBio(); error != StreamError::SUCCESS)
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
const ossl::Result<int> result = runIOLoop(&ossl::Ssl::read, buffer.data() + buffer.size() - bytesToRead,
|
||||
const ossl::Result<int> result = runIOLoop(&ossl::Ssl::read, !options.noBlock,
|
||||
buffer.data() + buffer.size() - bytesToRead,
|
||||
static_cast<int>(bytesToRead));
|
||||
if (result.isError())
|
||||
{
|
||||
@@ -216,9 +226,9 @@ StreamFeatures SSLStream::getFeatures()
|
||||
.tell = false,
|
||||
.seek = false,
|
||||
.readOptions = {
|
||||
.partial = false,
|
||||
.peek = false,
|
||||
.noBlock = false
|
||||
.partial = true,
|
||||
.peek = true,
|
||||
.noBlock = true
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -247,18 +257,20 @@ StreamError SSLStream::bioToBase() noexcept
|
||||
StreamError SSLStream::baseToBio() noexcept
|
||||
{
|
||||
std::array<std::uint8_t, BIO_BUFFER_SIZE> buffer;
|
||||
std::size_t toRead = externalBio_.getWriteGuarantee();
|
||||
|
||||
while (true)
|
||||
{
|
||||
std::size_t bytes = 0;
|
||||
std::size_t maxBytes = std::min(BIO_BUFFER_SIZE - externalBio_.ctrlWPending(), buffer.size());
|
||||
std::size_t maxBytes = std::min(toRead, buffer.size());
|
||||
|
||||
if (maxBytes == 0)
|
||||
{
|
||||
// buffer is full
|
||||
return StreamError::SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
if (const StreamError error = base_->readRaw(buffer.data(), maxBytes,{.partial = true, .noBlock = true},
|
||||
if (const StreamError error = base_->readRaw(buffer.data(), maxBytes, {.partial = true, .noBlock = true},
|
||||
&bytes); error != StreamError::SUCCESS)
|
||||
{
|
||||
return error;
|
||||
@@ -274,6 +286,13 @@ StreamError SSLStream::baseToBio() noexcept
|
||||
return StreamError::UNKNOWN_ERROR;
|
||||
}
|
||||
MIJIN_ASSERT(result.getValue() == static_cast<int>(bytes), "BIO reported more bytes in buffer than it actually accepted?");
|
||||
toRead -= bytes;
|
||||
}
|
||||
|
||||
if (const ossl::Error error = externalBio_.flush(); !error.isSuccess())
|
||||
{
|
||||
return StreamError::UNKNOWN_ERROR;
|
||||
}
|
||||
return StreamError::SUCCESS;
|
||||
}
|
||||
} // namespace shiken
|
||||
|
||||
Reference in New Issue
Block a user