IDState* ids = &dss->idStates[queryId];
int origFD = ids->origFD;
- if(origFD < 0 && ids->du == nullptr) // duplicate
+ if(origFD < 0) // duplicate
continue;
+ auto du = ids->du;
/* setting age to 0 to prevent the maintainer thread from
cleaning this IDS while we process the response.
We have already a copy of the origFD, so it would
and the other thread has not incremented the outstanding counter, so we don't
want it to be decremented twice. */
--dss->outstanding; // you'd think an attacker could game this, but we're using connected socket
+ } else {
+ du = nullptr;
}
+ ids->du = nullptr;
if(dh->tc && g_truncateTC) {
truncateTC(response, &responseLen, responseSize, consumed);
}
if (ids->cs && !ids->cs->muted) {
- if (ids->du) {
+ if (du) {
#ifdef HAVE_DNS_OVER_HTTPS
// DoH query
- ids->du->query = std::string(response, responseLen);
- if (send(ids->du->rsock, &ids->du, sizeof(ids->du), 0) != sizeof(ids->du)) {
- delete ids->du;
+ du->query = std::string(response, responseLen);
+ if (send(du->rsock, &du, sizeof(du), 0) != sizeof(du)) {
+ delete du;
}
#endif /* HAVE_DNS_OVER_HTTPS */
- ids->du = nullptr;
+ du = nullptr;
}
else {
ComboAddress empty;
unsigned int idOffset = (ss->idOffset++) % ss->idStates.size();
IDState* ids = &ss->idStates[idOffset];
ids->age = 0;
- ids->du = nullptr;
+ DOHUnit* du = nullptr;
+
+ if (ids->origFD != -1) {
+ du = ids->du;
+ }
int oldFD = ids->origFD.exchange(cs.udpFD);
if(oldFD < 0) {
- // if we are reusing, no change in outstanding
++ss->outstanding;
+ /* either it was already -1 so no DOH unit to handle,
+ or someone handled it before us */
+ du = nullptr;
}
else {
+ // if we are reusing, no change in outstanding
++ss->reuseds;
++g_stats.downstreamTimeouts;
+ ids->du = nullptr;
+ handleDOHTimeout(du);
}
ids->cs = &cs;
so the sooner the better any way since we _will_
decrement it.
*/
+ auto oldDU = ids.du;
+
if (ids.origFD.exchange(-1) != origFD) {
/* this state has been altered in the meantime,
don't go anywhere near it */
continue;
}
+ handleDOHTimeout(oldDU);
ids.du = nullptr;
ids.age = 0;
dss->reuseds++;
+#include "config.h"
+#include "doh.hh"
+
+#ifdef HAVE_DNS_OVER_HTTPS
#define H2O_USE_EPOLL 1
#include <errno.h>
int dohresponsepair[2]{-1,-1};
};
+void handleDOHTimeout(DOHUnit* oldDU)
+{
+ if (oldDU == nullptr) {
+ return;
+ }
+
+/* we are about to erase an existing DU */
+ oldDU->error = true;
+ oldDU->status_code = 502;
+
+ if (send(oldDU->rsock, &oldDU, sizeof(oldDU), 0) != sizeof(oldDU)) {
+ delete oldDU;
+ oldDU = nullptr;
+ }
+}
+
static void on_socketclose(void *data)
{
DOHAcceptContext* ctx = reinterpret_cast<DOHAcceptContext*>(data);
return -1;
}
+ ComboAddress dest = du->dest;
unsigned int idOffset = (ss->idOffset++) % ss->idStates.size();
IDState* ids = &ss->idStates[idOffset];
ids->age = 0;
- ids->du = du;
+ DOHUnit* oldDU = nullptr;
+ if (ids->origFD != -1) {
+ oldDU = ids->du;
+ }
- int oldFD = ids->origFD.exchange(cs.udpFD);
- if(oldFD < 0) {
+ int oldFD = ids->origFD.exchange(0);
+ if (oldFD < 0) {
// if we are reusing, no change in outstanding
++ss->outstanding;
}
else {
++ss->reuseds;
++g_stats.downstreamTimeouts;
+ /* origFD is not -1 anymore, we can't touch it */
+ oldDU = nullptr;
}
+ handleDOHTimeout(oldDU);
+
+ ids->du = du;
+
ids->cs = &cs;
ids->origID = dh->id;
setIDStateFromDNSQuestion(*ids, dq, std::move(qname));
We need to keep track of which one it is since we may
want to use the real but not the listening addr to reply.
*/
- if (du->dest.sin4.sin_family != 0) {
- ids->origDest = du->dest;
+ if (dest.sin4.sin_family != 0) {
+ ids->origDest = dest;
ids->destHarvested = true;
}
else {
++dsc->df->d_errorresponses;
}
+
delete du;
}
catch(...) {
throw runtime_error("DOH thread failed to launch");
}
+
+#else /* HAVE_DNS_OVER_HTTPS */
+
+void handleDOHTimeout(DOHUnit* oldDU)
+{
+}
+
+#endif /* HAVE_DNS_OVER_HTTPS */