#include "dnsdist-ecs.hh"
#include "dnsdist-proxy-protocol.hh"
-
static void sendBackDOQUnit(DOQUnitUniquePtr&& du, const char* description);
class DOQServerConfig
{
#if 0
#define DEBUGLOG_ENABLED
-#define DEBUGLOG(x) std::cerr<<x<<std::endl;
+#define DEBUGLOG(x) std::cerr << x << std::endl;
#else
#define DEBUGLOG(x)
#endif
dr.ids.doqu = std::move(du);
-
if (!processResponse(dr.ids.doqu->response, *localRespRuleActions, *localCacheInsertedRespRuleActions, dr, false)) {
if (dr.ids.doqu) {
auto& ids = query.d_idstate;
DNSResponse dr(ids, query.d_buffer, downstream);
return dr;
- }
+ }
DOQUnitUniquePtr&& releaseDU()
{
std::shared_ptr<DOQTCPCrossQuerySender> DOQCrossProtocolQuery::s_sender = std::make_shared<DOQTCPCrossQuerySender>();
-/* Always called from the main DoQ thread */
static void handleResponse(DOQFrontend& df, Connection& conn, const uint64_t streamID, const PacketBuffer& response)
{
if (response.size() == 0) {
quiche_conn_stream_shutdown(conn.d_conn.get(), streamID, QUICHE_SHUTDOWN_WRITE, 0x5);
- } else {
+ }
+ else {
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) };
+ const uint8_t sizeBytes[] = {static_cast<uint8_t>(responseSize / 256), static_cast<uint8_t>(responseSize % 256)};
auto res = quiche_conn_stream_send(conn.d_conn.get(), streamID, sizeBytes, sizeof(sizeBytes), false);
if (res == sizeof(sizeBytes)) {
res = quiche_conn_stream_send(conn.d_conn.get(), streamID, response.data(), response.size(), true);
int rng = open("/dev/urandom", O_RDONLY);
if (rng < 0) {
return std::nullopt;
-
}
PacketBuffer buffer;
buffer.resize(LOCAL_CONN_ID_LEN);
{
auto quicheConn = QuicheConnection(quiche_accept(serverSideID.data(), serverSideID.size(),
originalDestinationID.data(), originalDestinationID.size(),
- (struct sockaddr*) &local,
+ (struct sockaddr*)&local,
local.getSocklen(),
- (struct sockaddr*) &peer,
+ (struct sockaddr*)&peer,
peer.getSocklen(),
- config.get()), quiche_conn_free);
+ config.get()),
+ quiche_conn_free);
auto conn = Connection(peer, std::move(quicheConn));
- auto pair = s_connections.emplace(serverSideID, std::move(conn));
+ auto pair = s_connections.emplace(serverSideID, std::move(conn));
return pair.first->second;
}
-static void flushEgress(Socket& sock, Connection& conn) {
+static void flushEgress(Socket& sock, Connection& conn)
+{
std::array<uint8_t, MAX_DATAGRAM_SIZE> out;
quiche_send_info send_info;
if (written < 0) {
return;
}
-
+ // FIXME pacing (as send_info.at should tell us when to send the packet) ?
sock.sendTo(reinterpret_cast<const char*>(out.data()), written, conn.d_peer);
}
-
- // FIXME: update timers
}
std::unique_ptr<CrossProtocolQuery> getDOQCrossProtocolQueryFromDQ(DNSQuestion& dq, bool isResponse)
auto du = std::move(dq.ids.doqu);
if (&dq.ids != &du->ids) {
- du->ids = std::move(dq.ids);
+ du->ids = std::move(dq.ids);
}
du->ids.origID = dq.getHeader()->id;
{
const auto handleImmediateResponse = [](DOQUnitUniquePtr&& du, const char* reason) {
DEBUGLOG("handleImmediateResponse() reason=" << reason);
- auto conn = getConnection(du->serverConnID);
- handleResponse(*du->dsc->df, *conn, du->streamID, du->response);
- /* so the unique pointer is stored in the InternalState which itself is stored in the unique pointer itself. We likely need
- a better design, but for now let's just reset the internal one since we know it is no longer needed. */
- du->ids.doqu.reset();
+ auto conn = getConnection(du->serverConnID);
+ handleResponse(*du->dsc->df, *conn, du->streamID, du->response);
+ du->ids.doqu.reset();
};
auto& ids = unit->ids;
ClientState& cs = *dsc->cs;
if (du->query.size() < sizeof(dnsheader)) {
- // ++dnsdist::metrics::g_stats.nonCompliantQueries;
- // ++cs.nonCompliantQueries;
+ ++dnsdist::metrics::g_stats.nonCompliantQueries;
+ ++cs.nonCompliantQueries;
struct dnsheader* dh = reinterpret_cast<struct dnsheader*>(du->query.data());
dh->rcode = RCode::ServFail;
dh->qr = true;
return;
}
- // ++cs.queries;
- // ++dnsdist::metrics::g_stats.queries;
+ ++cs.queries;
+ ++dnsdist::metrics::g_stats.queries;
du->ids.queryRealTime.start();
{
return;
}
+ ++dnsdist::metrics::g_stats.responses;
+ if (du->ids.cs != nullptr) {
+ ++du->ids.cs->responses;
+ }
+
if (result != ProcessQueryResult::PassToBackend) {
handleImmediateResponse(std::move(du), "DoQ no backend available");
return;
else {
DEBUGLOG("Connection not established");
}
- /* FIXME: we should handle timeouts */
- // pacing QUIC ?
- // quiche_send_info.at Queue avec les paquets a envoyer par date.
}
+
for (auto conn = s_connections.begin(); conn != s_connections.end();) {
quiche_conn_on_timeout(conn->second.d_conn.get());
quiche_conn_stats(conn->second.d_conn.get(), &stats);
quiche_conn_path_stats(conn->second.d_conn.get(), 0, &path_stats);
- DEBUGLOG("Connection closed, recv="<<stats.recv<<" sent="<<stats.sent<<" lost="<<stats.lost<<" rtt="<<path_stats.rtt<<"ns cwnd="<<path_stats.cwnd);
+ DEBUGLOG("Connection closed, recv=" << stats.recv << " sent=" << stats.sent << " lost=" << stats.lost << " rtt=" << path_stats.rtt << "ns cwnd=" << path_stats.cwnd);
#endif
conn = s_connections.erase(conn);
- } else {
+ }
+ else {
++conn;
}
}