struct ExpectedStep
{
public:
- enum class ExpectedRequest { handshake, connect, read, write, close };
+ enum class ExpectedRequest { handshakeClient, readFromClient, writeToClient, closeClient, connectToBackend, readFromBackend, writeToBackend, closeBackend };
ExpectedStep(ExpectedRequest r, IOState n, size_t b = 0, std::function<void(int descriptor, const ExpectedStep& step)> fn = nullptr): cb(fn), request(r), nextState(n), bytes(b)
{
};
static std::deque<ExpectedStep> s_steps;
-static ExpectedStep getStep()
-{
- BOOST_REQUIRE(!s_steps.empty());
- auto res = s_steps.front();
- s_steps.pop_front();
- return res;
-}
static PacketBuffer s_readBuffer;
static PacketBuffer s_writeBuffer;
std::ostream& operator<<(std::ostream &os, const ExpectedStep::ExpectedRequest d)
{
- static const std::vector<std::string> requests = { "handshake", "connect", "read", "write", "close" };
+ static const std::vector<std::string> requests = { "handshake with client", "read from client", "write to client", "close connection to client", "connect to the backend", "read from the backend", "write to the backend", "close connection to backend" };
os<<requests.at(static_cast<size_t>(d));
return os;
}
IOState tryHandshake() override
{
auto step = getStep();
- BOOST_REQUIRE_EQUAL(step.request, ExpectedStep::ExpectedRequest::handshake);
+ BOOST_REQUIRE_EQUAL(step.request, ExpectedStep::ExpectedRequest::handshakeClient);
return step.nextState;
}
}
auto step = getStep();
- BOOST_REQUIRE_EQUAL(step.request, ExpectedStep::ExpectedRequest::write);
+ BOOST_REQUIRE_EQUAL(step.request, !d_client ? ExpectedStep::ExpectedRequest::writeToClient : ExpectedStep::ExpectedRequest::writeToBackend);
if (step.bytes == 0) {
if (step.nextState == IOState::NeedWrite) {
}
auto step = getStep();
- BOOST_REQUIRE_EQUAL(step.request, ExpectedStep::ExpectedRequest::read);
+ BOOST_REQUIRE_EQUAL(step.request, !d_client ? ExpectedStep::ExpectedRequest::readFromClient : ExpectedStep::ExpectedRequest::readFromBackend);
if (step.bytes == 0) {
if (step.nextState == IOState::NeedRead) {
if (step.bytes < toRead) {
toRead = step.bytes;
}
+
BOOST_REQUIRE_GE(buffer.size(), toRead);
BOOST_REQUIRE_GE(externalBuffer.size(), toRead);
IOState tryConnect(bool fastOpen, const ComboAddress& remote) override
{
auto step = getStep();
- BOOST_REQUIRE_EQUAL(step.request, ExpectedStep::ExpectedRequest::connect);
-
- if (step.cb) {
- step.cb(d_descriptor, step);
- }
+ BOOST_REQUIRE_EQUAL(step.request, ExpectedStep::ExpectedRequest::connectToBackend);
return step.nextState;
}
void close() override
{
auto step = getStep();
- BOOST_REQUIRE_EQUAL(step.request, ExpectedStep::ExpectedRequest::close);
+ BOOST_REQUIRE_EQUAL(step.request, !d_client ? ExpectedStep::ExpectedRequest::closeClient : ExpectedStep::ExpectedRequest::closeBackend);
}
bool hasBufferedData() const override
return 0;
}
private:
+ ExpectedStep getStep() const
+ {
+ BOOST_REQUIRE(!s_steps.empty());
+ auto step = s_steps.front();
+ s_steps.pop_front();
+
+ if (step.cb) {
+ step.cb(d_descriptor, step);
+ }
+
+ return step;
+ }
+
const int d_descriptor;
bool d_client{false};
};
gettimeofday(tv, nullptr); // MANDATORY
- for (const auto fd : ready) {
+ /* 'ready' might be altered by a callback while we are iterating */
+ const auto readyFDs = ready;
+ for (const auto fd : readyFDs) {
{
const auto& it = d_readCallbacks.find(fd);
s_readBuffer = query;
s_writeBuffer.clear();
s_steps = {
- { ExpectedStep::ExpectedRequest::handshake, IOState::Done },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
};
s_processQuery = [](DNSQuestion& dq, ClientState& cs, LocalHolders& holders, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
return ProcessQueryResult::Drop;
s_readBuffer = query;
s_writeBuffer.clear();
s_steps = {
- { ExpectedStep::ExpectedRequest::handshake, IOState::Done },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, 65537 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 0 },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 65537 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 0 },
+ { ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
};
s_processQuery = [](DNSQuestion& dq, ClientState& cs, LocalHolders& holders, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
// Would be nicer to actually turn it into a response
s_readBuffer = query;
s_writeBuffer.clear();
s_steps = {
- { ExpectedStep::ExpectedRequest::handshake, IOState::NeedWrite },
- { ExpectedStep::ExpectedRequest::handshake, IOState::NeedRead },
- { ExpectedStep::ExpectedRequest::handshake, IOState::Done },
- { ExpectedStep::ExpectedRequest::read, IOState::NeedRead, 1 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 1 },
- { ExpectedStep::ExpectedRequest::read, IOState::NeedRead, query.size() - 3 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 1 },
- { ExpectedStep::ExpectedRequest::write, IOState::NeedWrite, query.size() - 1},
- { ExpectedStep::ExpectedRequest::write, IOState::Done, 1 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 0 },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::handshakeClient, IOState::NeedWrite },
+ { ExpectedStep::ExpectedRequest::handshakeClient, IOState::NeedRead },
+ { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::NeedRead, 1 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 1 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::NeedRead, query.size() - 3 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 1 },
+ { ExpectedStep::ExpectedRequest::writeToClient, IOState::NeedWrite, query.size() - 1},
+ { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 1 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 0 },
+ { ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
};
s_processQuery = [](DNSQuestion& dq, ClientState& cs, LocalHolders& holders, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
// Would be nicer to actually turn it into a response
s_readBuffer = query;
s_writeBuffer.clear();
s_steps = {
- { ExpectedStep::ExpectedRequest::handshake, IOState::Done },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
};
s_processQuery = [](DNSQuestion& dq, ClientState& cs, LocalHolders& holders, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
throw std::runtime_error("Something unexpected happened");
size_t count = 10000;
s_readBuffer.clear();
s_writeBuffer.clear();
- s_steps = { { ExpectedStep::ExpectedRequest::handshake, IOState::Done } };
+ s_steps = { { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done } };
for (size_t idx = 0; idx < count; idx++) {
s_readBuffer.insert(s_readBuffer.end(), query.begin(), query.end());
- s_steps.push_back({ ExpectedStep::ExpectedRequest::read, IOState::Done, 2 });
- s_steps.push_back({ ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 });
- s_steps.push_back({ ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() + 2 });
+ s_steps.push_back({ ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 });
+ s_steps.push_back({ ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, query.size() - 2 });
+ s_steps.push_back({ ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, query.size() + 2 });
};
- s_steps.push_back({ ExpectedStep::ExpectedRequest::read, IOState::Done, 0 });
- s_steps.push_back({ ExpectedStep::ExpectedRequest::close, IOState::Done });
+ s_steps.push_back({ ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 0 });
+ s_steps.push_back({ ExpectedStep::ExpectedRequest::closeClient, IOState::Done });
size_t counter = 0;
s_processQuery = [&counter](DNSQuestion& dq, ClientState& cs, LocalHolders& holders, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
s_readBuffer = query;
s_writeBuffer.clear();
s_steps = {
- { ExpectedStep::ExpectedRequest::handshake, IOState::Done },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::NeedRead, query.size() - 2 - 2 },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::NeedRead, query.size() - 2 - 2 },
+ { ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
};
s_processQuery = [](DNSQuestion& dq, ClientState& cs, LocalHolders& holders, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
/* should not be reached */
s_readBuffer = query;
s_writeBuffer.clear();
s_steps = {
- { ExpectedStep::ExpectedRequest::handshake, IOState::Done },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
- { ExpectedStep::ExpectedRequest::write, IOState::NeedWrite, 1 },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::writeToClient, IOState::NeedWrite, 1 },
+ { ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
};
s_processQuery = [](DNSQuestion& dq, ClientState& cs, LocalHolders& holders, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
return ProcessQueryResult::SendAnswer;
s_writeBuffer.clear();
s_steps = {
- { ExpectedStep::ExpectedRequest::handshake, IOState::Done },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, s_proxyProtocolMinimumHeaderSize },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, proxyPayload.size() - s_proxyProtocolMinimumHeaderSize },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, 65537 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, 65537 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 0 },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, s_proxyProtocolMinimumHeaderSize },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, proxyPayload.size() - s_proxyProtocolMinimumHeaderSize },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 65537 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 65537 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 0 },
+ { ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
};
s_processQuery = [](DNSQuestion& dq, ClientState& cs, LocalHolders& holders, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
return ProcessQueryResult::SendAnswer;
s_writeBuffer.clear();
s_steps = {
- { ExpectedStep::ExpectedRequest::handshake, IOState::Done },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, s_proxyProtocolMinimumHeaderSize },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, s_proxyProtocolMinimumHeaderSize },
+ { ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
};
s_processQuery = [](DNSQuestion& dq, ClientState& cs, LocalHolders& holders, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
return ProcessQueryResult::SendAnswer;
s_writeBuffer.clear();
s_steps = {
- { ExpectedStep::ExpectedRequest::handshake, IOState::Done },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, s_proxyProtocolMinimumHeaderSize },
- { ExpectedStep::ExpectedRequest::read, IOState::NeedRead, proxyPayload.size() - s_proxyProtocolMinimumHeaderSize - 1},
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, s_proxyProtocolMinimumHeaderSize },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::NeedRead, proxyPayload.size() - s_proxyProtocolMinimumHeaderSize - 1},
+ { ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
};
s_processQuery = [](DNSQuestion& dq, ClientState& cs, LocalHolders& holders, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
return ProcessQueryResult::SendAnswer;
const uint8_t sizeBytes[] = { static_cast<uint8_t>(querySize / 256), static_cast<uint8_t>(querySize % 256) };
query.insert(query.begin(), sizeBytes, sizeBytes + 2);
- g_verbose = true;
-
g_proxyProtocolACL.clear();
{
s_backendWriteBuffer.clear();
s_steps = {
- { ExpectedStep::ExpectedRequest::handshake, IOState::Done },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, query.size() - 2 },
/* opening a connection to the backend */
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 0 },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, query.size() },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, query.size() },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 0 },
/* closing client connection */
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
/* closing a connection to the backend */
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
};
s_processQuery = [tlsCtx](DNSQuestion& dq, ClientState& cs, LocalHolders& holders, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
s_backendWriteBuffer.clear();
s_steps = {
- { ExpectedStep::ExpectedRequest::handshake, IOState::Done },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, query.size() - 2 },
/* opening a connection to the backend */
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, query.size() },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, query.size() - 2 },
/* closing client connection */
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
/* closing a connection to the backend */
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
};
s_processQuery = [tlsCtx](DNSQuestion& dq, ClientState& cs, LocalHolders& holders, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
s_backendWriteBuffer.clear();
s_steps = {
- { ExpectedStep::ExpectedRequest::handshake, IOState::Done },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, query.size() - 2 },
/* opening a connection to the backend */
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, query.size() },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, query.size() - 2 },
/* closing client connection */
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
/* closing a connection to the backend */
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
};
s_processQuery = [tlsCtx](DNSQuestion& dq, ClientState& cs, LocalHolders& holders, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
s_backendWriteBuffer.clear();
s_steps = {
- { ExpectedStep::ExpectedRequest::handshake, IOState::Done },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, query.size() - 2 },
/* opening a connection to the backend */
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, query.size() },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, query.size() - 2 },
/* closing client connection */
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
/* closing a connection to the backend */
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
};
s_processQuery = [tlsCtx](DNSQuestion& dq, ClientState& cs, LocalHolders& holders, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
s_backendWriteBuffer.clear();
s_steps = {
- { ExpectedStep::ExpectedRequest::handshake, IOState::Done },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, query.size() - 2 },
/* connect to backend */
- { ExpectedStep::ExpectedRequest::connect, IOState::NeedWrite, 0, [&threadData](int desc, const ExpectedStep& step) {
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::NeedWrite, 0, [&threadData](int desc, const ExpectedStep& step) {
/* set the outgoing descriptor (backend connection) as ready */
dynamic_cast<MockupFDMultiplexer*>(threadData.mplexer.get())->setReady(desc);
}
},
/* send query */
- { ExpectedStep::ExpectedRequest::write, IOState::NeedWrite, 1 },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() - 1 },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::NeedWrite, 1 },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, query.size() - 1 },
/* read response */
- { ExpectedStep::ExpectedRequest::read, IOState::NeedRead, 1 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 1 },
- { ExpectedStep::ExpectedRequest::read, IOState::NeedRead, query.size() - 3 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 1 },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::NeedRead, 1 },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, 1 },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::NeedRead, query.size() - 3 },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, 1 },
/* write response to client */
- { ExpectedStep::ExpectedRequest::write, IOState::NeedWrite, query.size() - 1 },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, 1 },
+ { ExpectedStep::ExpectedRequest::writeToClient, IOState::NeedWrite, query.size() - 1 },
+ { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 1 },
/* read second query */
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, query.size() - 2 },
/* write second query to backend */
- { ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, query.size() },
/* read second response */
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, query.size() - 2 },
/* write second response */
- { ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() },
+ { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, query.size() },
/* read from client */
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 0 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 0 },
/* close connection to client */
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
/* close connection to the backend, eventually */
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
};
auto backend = std::make_shared<DownstreamState>(ComboAddress("192.0.2.42:53"), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);
s_backendWriteBuffer.clear();
s_steps = {
- { ExpectedStep::ExpectedRequest::handshake, IOState::Done },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, query.size() - 2 },
/* opening a connection to the backend (5 tries by default) */
- { ExpectedStep::ExpectedRequest::connect, IOState::Done, 0, [](int descriptor, const ExpectedStep& step) {
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done, 0, [](int descriptor, const ExpectedStep& step) {
throw NetworkError("Connection refused by the backend");
}
},
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
- { ExpectedStep::ExpectedRequest::connect, IOState::Done, 0, [](int descriptor, const ExpectedStep& step) {
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done, 0, [](int descriptor, const ExpectedStep& step) {
throw NetworkError("Connection refused by the backend");
}
},
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
- { ExpectedStep::ExpectedRequest::connect, IOState::Done, 0, [](int descriptor, const ExpectedStep& step) {
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done, 0, [](int descriptor, const ExpectedStep& step) {
throw NetworkError("Connection refused by the backend");
}
},
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
- { ExpectedStep::ExpectedRequest::connect, IOState::Done, 0, [](int descriptor, const ExpectedStep& step) {
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done, 0, [](int descriptor, const ExpectedStep& step) {
throw NetworkError("Connection refused by the backend");
}
},
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
- { ExpectedStep::ExpectedRequest::connect, IOState::Done, 0, [](int descriptor, const ExpectedStep& step) {
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done, 0, [](int descriptor, const ExpectedStep& step) {
throw NetworkError("Connection refused by the backend");
}
},
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
/* closing client connection */
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
};
auto backend = std::make_shared<DownstreamState>(ComboAddress("192.0.2.42:53"), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);
backend->d_tlsCtx = tlsCtx;
s_backendWriteBuffer.clear();
s_steps = {
- { ExpectedStep::ExpectedRequest::handshake, IOState::Done },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, query.size() - 2 },
/* opening a connection to the backend (retrying 5 times) */
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::NeedWrite },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::NeedWrite },
/* closing client connection */
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
};
auto backend = std::make_shared<DownstreamState>(ComboAddress("192.0.2.42:53"), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);;
backend->d_tlsCtx = tlsCtx;
s_backendWriteBuffer.clear();
s_steps = {
- { ExpectedStep::ExpectedRequest::handshake, IOState::Done },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, query.size() - 2 },
/* opening a connection to the backend */
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() },
- { ExpectedStep::ExpectedRequest::read, IOState::NeedRead, 0 },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, query.size() },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::NeedRead, 0 },
/* closing client connection */
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
};
auto backend = std::make_shared<DownstreamState>(ComboAddress("192.0.2.42:53"), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);;
backend->d_tlsCtx = tlsCtx;
s_backendWriteBuffer.clear();
s_steps = {
- { ExpectedStep::ExpectedRequest::handshake, IOState::Done },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, query.size() - 2 },
/* opening a connection to the backend, connection closed on first write (5 attempts) */
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, 0 },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, 0 },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, 0 },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, 0 },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, 0 },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, 0 },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, 0 },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, 0 },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, 0 },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, 0 },
/* closing client connection */
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
};
auto backend = std::make_shared<DownstreamState>(ComboAddress("192.0.2.42:53"), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);;
backend->d_tlsCtx = tlsCtx;
s_backendWriteBuffer.clear();
s_steps = {
- { ExpectedStep::ExpectedRequest::handshake, IOState::Done },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, query.size() - 2 },
/* opening a connection to the backend, connection closed on first write (5 attempts) */
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, 0 },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, 0 },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, 0 },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, 0 },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, 0 },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, 0 },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, 0 },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, 0 },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, query.size() },
/* reading the response */
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, query.size() - 2 },
/* send the response to the client */
- { ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() },
+ { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, query.size() },
/* client closes the connection */
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 0 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 0 },
/* closing client connection */
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
/* then eventually the backend one */
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
};
auto backend = std::make_shared<DownstreamState>(ComboAddress("192.0.2.42:53"), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);;
backend->d_tlsCtx = tlsCtx;
s_backendWriteBuffer.clear();
s_steps = {
- { ExpectedStep::ExpectedRequest::handshake, IOState::Done },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, query.size() - 2 },
/* opening a connection to the backend, connection closed on read, 5 attempts, last one succeeds */
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 0 },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 0 },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 0 },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 0 },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 0 },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, query.size() },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, 0 },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, query.size() },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, 0 },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, query.size() },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, 0 },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, query.size() },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, 0 },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, query.size() },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, 0 },
/* closing client connection */
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
};
auto backend = std::make_shared<DownstreamState>(ComboAddress("192.0.2.42:53"), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);;
backend->d_tlsCtx = tlsCtx;
s_backendWriteBuffer.clear();
s_steps = {
- { ExpectedStep::ExpectedRequest::handshake, IOState::Done },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, query.size() - 2 },
/* opening a connection to the backend, connection closed on read, 5 attempts, last one succeeds */
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 0 },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 0 },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 0 },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 0 },
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, query.size() },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, 0 },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, query.size() },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, 0 },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, query.size() },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, 0 },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, query.size() },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, 0 },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
/* this time it works */
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, query.size() },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, query.size() - 2 },
/* sending the response to the client */
- { ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() },
+ { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, query.size() },
/* client closes the connection */
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 0 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 0 },
/* closing client connection */
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
/* the eventually the backend one */
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
};
auto backend = std::make_shared<DownstreamState>(ComboAddress("192.0.2.42:53"), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);;
backend->d_tlsCtx = tlsCtx;
s_backendReadBuffer.insert(s_backendReadBuffer.end(), query.begin(), query.end());
}
- s_steps = { { ExpectedStep::ExpectedRequest::handshake, IOState::Done },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
+ s_steps = { { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, query.size() - 2 },
/* opening a connection to the backend */
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() + 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() + 2 }
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, query.size() + 2 },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, query.size() + 2 }
};
for (size_t idx = 0; idx < count - 1; idx++) {
/* read a new query */
- s_steps.push_back({ ExpectedStep::ExpectedRequest::read, IOState::Done, 2 });
- s_steps.push_back({ ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 });
+ s_steps.push_back({ ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 });
+ s_steps.push_back({ ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, query.size() - 2 });
/* pass it to the backend */
- s_steps.push_back({ ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() + 2 });
- s_steps.push_back({ ExpectedStep::ExpectedRequest::read, IOState::Done, 2 });
- s_steps.push_back({ ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 });
+ s_steps.push_back({ ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, query.size() + 2 });
+ s_steps.push_back({ ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, 2 });
+ s_steps.push_back({ ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, query.size() - 2 });
/* send the response */
- s_steps.push_back({ ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() + 2 });
+ s_steps.push_back({ ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, query.size() + 2 });
};
/* close the connection with the client */
- s_steps.push_back({ ExpectedStep::ExpectedRequest::close, IOState::Done });
+ s_steps.push_back({ ExpectedStep::ExpectedRequest::closeClient, IOState::Done });
/* eventually with the backend as well */
- s_steps.push_back({ ExpectedStep::ExpectedRequest::close, IOState::Done });
+ s_steps.push_back({ ExpectedStep::ExpectedRequest::closeBackend, IOState::Done });
auto backend = std::make_shared<DownstreamState>(ComboAddress("192.0.2.42:53"), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);;
backend->d_tlsCtx = tlsCtx;
backend->d_tlsCtx = tlsCtx;
/* enable out-of-order on the backend side as well */
backend->d_maxInFlightQueriesPerConn = 65536;
+ /* shorter than the client one */
+ backend->tcpRecvTimeout = 1;
TCPClientThreadData threadData;
threadData.mplexer = std::make_unique<MockupFDMultiplexer>();
struct timeval now;
gettimeofday(&now, nullptr);
- PacketBuffer query;
- GenericDNSPacketWriter<PacketBuffer> pwQ(query, DNSName("powerdns.com."), QType::A, QClass::IN, 0);
- pwQ.getHeader()->rd = 1;
+ std::vector<PacketBuffer> queries(5);
+ std::vector<PacketBuffer> responses(5);
+
+ size_t counter = 0;
+ size_t totalQueriesSize = 0;
+ for (auto& query : queries) {
+ GenericDNSPacketWriter<PacketBuffer> pwQ(query, DNSName("powerdns" + std::to_string(counter) + ".com."), QType::A, QClass::IN, 0);
+ pwQ.getHeader()->rd = 1;
+ pwQ.getHeader()->id = counter;
+ uint16_t querySize = static_cast<uint16_t>(query.size());
+ const uint8_t sizeBytes[] = { static_cast<uint8_t>(querySize / 256), static_cast<uint8_t>(querySize % 256) };
+ query.insert(query.begin(), sizeBytes, sizeBytes + 2);
+ totalQueriesSize += query.size();
+ ++counter;
+ }
- uint16_t querySize = static_cast<uint16_t>(query.size());
- const uint8_t sizeBytes[] = { static_cast<uint8_t>(querySize / 256), static_cast<uint8_t>(querySize % 256) };
- query.insert(query.begin(), sizeBytes, sizeBytes + 2);
+ counter = 0;
+ size_t totalResponsesSize = 0;
+ for (auto& response : responses) {
+ DNSName name("powerdns" + std::to_string(counter) + ".com.");
+ GenericDNSPacketWriter<PacketBuffer> pwR(response, name, QType::A, QClass::IN, 0);
+ pwR.getHeader()->qr = 1;
+ pwR.getHeader()->rd = 1;
+ pwR.getHeader()->ra = 1;
+ pwR.getHeader()->id = counter;
+ pwR.startRecord(name, QType::A, 7200, QClass::IN, DNSResourceRecord::ANSWER);
+ pwR.xfr32BitInt(0x01020304);
+ pwR.commit();
+
+ uint16_t responseSize = static_cast<uint16_t>(response.size());
+ const uint8_t sizeBytes[] = { static_cast<uint8_t>(responseSize / 256), static_cast<uint8_t>(responseSize % 256) };
+ response.insert(response.begin(), sizeBytes, sizeBytes + 2);
+ totalResponsesSize += response.size();
+ ++counter;
+ }
g_verbose = true;
g_proxyProtocolACL.clear();
{
- cerr<<"=> 5 OOOR queries to the backend, backend responds out of order"<<endl;
- s_readBuffer = query;
+ cerr<<"=> 5 OOOR queries to the backend, backend responds in reverse order"<<endl;
+ PacketBuffer expectedWriteBuffer;
+ PacketBuffer expectedBackendWriteBuffer;
+
+ s_readBuffer.clear();
+ for (const auto& query : queries) {
+ s_readBuffer.insert(s_readBuffer.end(), query.begin(), query.end());
+ }
+ expectedBackendWriteBuffer = s_readBuffer;
s_writeBuffer.clear();
-#warning TODOOOOOOOOOO
- s_backendReadBuffer = query;
+
+ s_backendReadBuffer.clear();
+ for (const auto& response : responses) {
+ /* reverse order */
+ s_backendReadBuffer.insert(s_backendReadBuffer.begin(), response.begin(), response.end());
+ }
+ expectedWriteBuffer = s_backendReadBuffer;
s_backendWriteBuffer.clear();
s_steps = {
- { ExpectedStep::ExpectedRequest::handshake, IOState::Done },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
+ { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done },
+ /* reading a query from the client (1) */
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, queries.at(0).size() - 2 },
/* opening a connection to the backend */
- { ExpectedStep::ExpectedRequest::connect, IOState::Done },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 2 },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, query.size() - 2 },
- { ExpectedStep::ExpectedRequest::write, IOState::Done, query.size() },
- { ExpectedStep::ExpectedRequest::read, IOState::Done, 0 },
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ /* sending query to the backend */
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, queries.at(0).size() },
+ /* no response ready yet */
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::NeedRead, 0 },
+ /* reading a query from the client (2) */
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, queries.at(1).size() - 2 },
+ /* sending query to the backend */
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, queries.at(1).size() },
+ /* no response ready yet */
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::NeedRead, 0 },
+ /* reading a query from the client (3) */
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, queries.at(2).size() - 2 },
+ /* sending query to the backend */
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, queries.at(2).size() },
+ /* no response ready yet */
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::NeedRead, 0 },
+ /* reading a query from the client (4) */
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, queries.at(3).size() - 2 },
+ /* sending query to the backend */
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, queries.at(3).size() },
+ /* no response ready yet */
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::NeedRead, 0 },
+ /* reading a query from the client (5) */
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, queries.at(4).size() - 2 },
+ /* sending query to the backend */
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, queries.at(4).size() },
+ /* no response ready yet, but the backend becomes ready */
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::NeedRead, 0, [&threadData](int desc, const ExpectedStep& step) {
+ /* set the outgoing descriptor (backend connection) as ready */
+ dynamic_cast<MockupFDMultiplexer*>(threadData.mplexer.get())->setReady(desc);
+ } },
+
+ /* no more queries from the client */
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::NeedRead, 0 },
+
+ /* reading a response from the backend */
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, responses.at(4).size() - 2 },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, responses.at(4).size() },
+ /* sending it to the client */
+ { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, responses.at(4).size() },
+
+ /* reading a response from the backend */
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, responses.at(3).size() - 2 },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, responses.at(3).size() },
+ /* sending it to the client */
+ { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, responses.at(3).size() },
+
+ /* reading a response from the backend */
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, responses.at(2).size() - 2 },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, responses.at(2).size() },
+ /* sending it to the client */
+ { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, responses.at(2).size() },
+
+ /* reading a response from the backend */
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, responses.at(1).size() - 2 },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, responses.at(1).size() },
+ /* sending it to the client */
+ { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, responses.at(1).size() },
+
+ /* reading a response from the backend */
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, responses.at(0).size() - 2 },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, responses.at(0).size() },
+ /* sending it to the client, the client descriptor becomes ready */
+ { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, responses.at(0).size(), [&threadData](int desc, const ExpectedStep& step) {
+ /* set the incoming descriptor (client connection) as ready */
+ dynamic_cast<MockupFDMultiplexer*>(threadData.mplexer.get())->setReady(desc);
+ } },
+
+ /* client is closing the connection */
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 0 },
/* closing client connection */
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
/* closing a connection to the backend */
- { ExpectedStep::ExpectedRequest::close, IOState::Done },
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
};
s_processQuery = [backend](DNSQuestion& dq, ClientState& cs, LocalHolders& holders, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
auto state = std::make_shared<IncomingTCPConnectionState>(ConnectionInfo(&localCS), threadData, now);
IncomingTCPConnectionState::handleIO(state, now);
- BOOST_CHECK_EQUAL(s_writeBuffer.size(), query.size());
- BOOST_CHECK(s_writeBuffer == query);
- BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), query.size());
- BOOST_CHECK(s_backendWriteBuffer == query);
+ while (threadData.mplexer->getWatchedFDCount(false) != 0 || threadData.mplexer->getWatchedFDCount(true) != 0) {
+ threadData.mplexer->run(&now);
+ }
+
+ BOOST_CHECK_EQUAL(s_writeBuffer.size(), totalResponsesSize);
+ BOOST_CHECK(s_writeBuffer == expectedWriteBuffer);
+ BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), totalQueriesSize);
+ BOOST_CHECK(s_backendWriteBuffer == expectedBackendWriteBuffer);
+
+ /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */
+ IncomingTCPConnectionState::clearAllDownstreamConnections();
+ }
+
+ {
+ cerr<<"=> 3 queries sent to the backend, 1 self-answered, 1 new query sent to the backend which responds to the first query right away, then to the last one, then the connection to the backend times out"<<endl;
+
+ // increase the client timeout for that test, we want the backend to timeout first
+ g_tcpRecvTimeout = 5;
+
+ PacketBuffer expectedWriteBuffer;
+ PacketBuffer expectedBackendWriteBuffer;
+
+ s_readBuffer.clear();
+ for (const auto& query : queries) {
+ s_readBuffer.insert(s_readBuffer.end(), query.begin(), query.end());
+ }
+ s_writeBuffer.clear();
+
+ s_backendReadBuffer.clear();
+ s_backendReadBuffer.insert(s_backendReadBuffer.end(), responses.at(0).begin(), responses.at(0).end());
+ s_backendReadBuffer.insert(s_backendReadBuffer.end(), responses.at(4).begin(), responses.at(4).end());
+
+ /* self-answered */
+ expectedWriteBuffer.insert(expectedWriteBuffer.end(), responses.at(3).begin(), responses.at(3).end());
+ /* from backend */
+ expectedWriteBuffer.insert(expectedWriteBuffer.end(), responses.at(0).begin(), responses.at(0).end());
+ expectedWriteBuffer.insert(expectedWriteBuffer.end(), responses.at(4).begin(), responses.at(4).end());
+
+ s_backendWriteBuffer.clear();
+
+ expectedBackendWriteBuffer.insert(expectedBackendWriteBuffer.end(), queries.at(0).begin(), queries.at(0).end());
+ expectedBackendWriteBuffer.insert(expectedBackendWriteBuffer.end(), queries.at(1).begin(), queries.at(1).end());
+ expectedBackendWriteBuffer.insert(expectedBackendWriteBuffer.end(), queries.at(2).begin(), queries.at(2).end());
+ expectedBackendWriteBuffer.insert(expectedBackendWriteBuffer.end(), queries.at(4).begin(), queries.at(4).end());
+
+
+ bool timeout = false;
+ s_steps = {
+ { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done },
+ /* reading a query from the client (1) */
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, queries.at(0).size() - 2 },
+ /* opening a connection to the backend */
+ { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done },
+ /* sending query to the backend */
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, queries.at(0).size() },
+ /* no response ready yet */
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::NeedRead, 0 },
+ /* reading a query from the client (2) */
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, queries.at(1).size() - 2 },
+ /* sending query to the backend */
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, queries.at(1).size() },
+ /* no response ready yet */
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::NeedRead, 0 },
+ /* reading a query from the client (3) */
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, queries.at(2).size() - 2 },
+ /* sending query to the backend */
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, queries.at(2).size() },
+ /* no response ready yet */
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::NeedRead, 0 },
+ /* reading a query from the client (4) */
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, queries.at(3).size() - 2 },
+ /* sending the response right away (self-answered) */
+ { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, responses.at(3).size() },
+ /* reading a query from the client (5) */
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, queries.at(4).size() - 2 },
+ /* sending query to the backend (5) */
+ { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, queries.at(4).size() },
+ /* reading a response from the backend (1) */
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, responses.at(0).size() - 2 },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, responses.at(0).size(), [&threadData](int desc, const ExpectedStep& step) {
+ /* set the backend descriptor as ready */
+ dynamic_cast<MockupFDMultiplexer*>(threadData.mplexer.get())->setReady(desc);
+ } },
+ /* sending it to the client (1) */
+ { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, responses.at(0).size(), [&threadData](int desc, const ExpectedStep& step) {
+ /* set the client descriptor as NOT ready */
+ dynamic_cast<MockupFDMultiplexer*>(threadData.mplexer.get())->setNotReady(desc);
+ } },
+ /* reading from the client (not ready) */
+ { ExpectedStep::ExpectedRequest::readFromClient, IOState::NeedRead, 0 },
+ /* reading a response from the backend (5) */
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, responses.at(4).size() - 2 },
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, responses.at(4).size() },
+ /* sending it to the client (5) */
+ { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, responses.at(4).size() },
+
+ /* try to read from the backend but there is no answer ready yet */
+ { ExpectedStep::ExpectedRequest::readFromBackend, IOState::NeedRead, 0, [&threadData, &timeout](int desc, const ExpectedStep& step) {
+ /* set the backend descriptor as NOT ready */
+ dynamic_cast<MockupFDMultiplexer*>(threadData.mplexer.get())->setNotReady(desc);
+ timeout = true;
+ } },
+
+ /* A timeout occurs */
+
+ /* closing client connection */
+ { ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
+
+ /* closing a connection to the backend */
+ { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
+ };
+
+ s_processQuery = [backend,&responses](DNSQuestion& dq, ClientState& cs, LocalHolders& holders, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ static size_t count = 0;
+ if (count++ == 3) {
+ /* self answered */
+ dq.getMutableData() = responses.at(3);
+ /* remove the length */
+ dq.getMutableData().erase(dq.getMutableData().begin(), dq.getMutableData().begin() + 2);
+
+ return ProcessQueryResult::SendAnswer;
+ }
+ selectedBackend = backend;
+ return ProcessQueryResult::PassToBackend;
+ };
+ s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRulactions, DNSResponse& dr, bool muted) -> bool {
+ return true;
+ };
+
+ auto state = std::make_shared<IncomingTCPConnectionState>(ConnectionInfo(&localCS), threadData, now);
+ IncomingTCPConnectionState::handleIO(state, now);
+
+ while (!timeout && (threadData.mplexer->getWatchedFDCount(false) != 0 || threadData.mplexer->getWatchedFDCount(true) != 0)) {
+ threadData.mplexer->run(&now);
+ }
+
+ struct timeval later = now;
+ later.tv_sec += backend->tcpRecvTimeout + 1;
+ auto expiredConns = threadData.mplexer->getTimeouts(later, false);
+ BOOST_CHECK_EQUAL(expiredConns.size(), 1U);
+ for (const auto& cbData : expiredConns) {
+ if (cbData.second.type() == typeid(std::shared_ptr<TCPConnectionToBackend>)) {
+ auto cbState = boost::any_cast<std::shared_ptr<TCPConnectionToBackend>>(cbData.second);
+ cbState->handleTimeout(later, false);
+ }
+ }
+
+ BOOST_CHECK_EQUAL(s_writeBuffer.size(), expectedWriteBuffer.size());
+ BOOST_CHECK(s_writeBuffer == expectedWriteBuffer);
+ BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), expectedBackendWriteBuffer.size());
+ BOOST_CHECK(s_backendWriteBuffer == expectedBackendWriteBuffer);
+
/* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */
IncomingTCPConnectionState::clearAllDownstreamConnections();
+
+ // restore the client timeout
+ g_tcpRecvTimeout = 2;
}
}
#warning TODO:
-// proxy protocol to backend?
-
// OOOR: OOOR enabled but packet cache hit
// OOOR: OOOR enabled but backend answers very fast
// OOOR: OOOR, get 10 queries before the backend can answer. backend doesn't support OOOR, we should get 10 connections. Check that we do reuse them on two subsequent queries