}
}
-static void prependSizeToTCPQuery(PacketBuffer& buffer)
+static void prependSizeToTCPQuery(PacketBuffer& buffer, size_t proxyProtocolPayloadSize)
{
- uint16_t queryLen = buffer.size();
+ if (buffer.size() <= proxyProtocolPayloadSize) {
+ throw std::runtime_error("The payload size is smaller or equal to the buffer size");
+ }
+
+ uint16_t queryLen = proxyProtocolPayloadSize > 0 ? (buffer.size() - proxyProtocolPayloadSize) : buffer.size();
const uint8_t sizeBytes[] = { static_cast<uint8_t>(queryLen / 256), static_cast<uint8_t>(queryLen % 256) };
/* prepend the size. Yes, this is not the most efficient way but it prevents mistakes
that could occur if we had to deal with the size during the processing,
especially alignment issues */
- buffer.insert(buffer.begin(), sizeBytes, sizeBytes + 2);
+ buffer.insert(buffer.begin() + proxyProtocolPayloadSize, sizeBytes, sizeBytes + 2);
}
bool IncomingTCPConnectionState::canAcceptNewQueries(const struct timeval& now)
setIDStateFromDNSQuestion(ids, dq, std::move(qname));
ids.origID = ntohs(dh->id);
- prependSizeToTCPQuery(state->d_buffer);
+ prependSizeToTCPQuery(state->d_buffer, 0);
auto downstreamConnection = state->getDownstreamConnection(ds, dq.proxyProtocolValues, now);
auto query = std::move(tmp->query);
auto downstreamServer = std::move(tmp->downstream);
+ auto proxyProtocolPayloadSize = tmp->proxyProtocolPayloadSize;
std::shared_ptr<TCPQuerySender> tqs = tmp->getTCPQuerySender();
delete tmp;
tmp = nullptr;
auto downstream = DownstreamConnectionsManager::getConnectionToDownstream(threadData->mplexer, downstreamServer, now);
-#warning FIXME: what if a proxy protocol payload was inserted?
- prependSizeToTCPQuery(query.d_buffer);
+ prependSizeToTCPQuery(query.d_buffer, proxyProtocolPayloadSize);
downstream->queueQuery(tqs, std::move(query));
}
catch (...) {
return addProxyProtocol(dq.getMutableData(), payload);
}
-bool addProxyProtocol(DNSQuestion& dq)
+bool addProxyProtocol(DNSQuestion& dq, size_t* payloadSize)
{
auto payload = getProxyProtocolPayload(dq);
+ if (payloadSize != nullptr) {
+ *payloadSize = payload.size();
+ }
+
return addProxyProtocol(dq, payload);
}
std::string getProxyProtocolPayload(const DNSQuestion& dq);
-bool addProxyProtocol(DNSQuestion& dq);
+bool addProxyProtocol(DNSQuestion& dq, size_t* proxyProtocolPayloadSize = nullptr);
bool addProxyProtocol(DNSQuestion& dq, const std::string& payload);
bool addProxyProtocol(PacketBuffer& buffer, const std::string& payload);
bool addProxyProtocol(PacketBuffer& buffer, bool tcp, const ComboAddress& source, const ComboAddress& destination, const std::vector<ProxyProtocolValue>& values);
setNonBlocking(dohresponsepair[1]);
- if (pipe(fd) < 0) {
- close(dohquerypair[0]);
- close(dohquerypair[1]);
- close(dohresponsepair[0]);
- close(dohresponsepair[1]);
- unixDie("Creating a pipe for DNS over HTTPS");
- }
-
h2o_config_init(&h2o_config);
h2o_config.http2.idle_timeout = idleTimeout * 1000;
}
}
if (du->downstream->useProxyProtocol) {
- addProxyProtocol(dq);
+ size_t payloadSize = 0;
+ if (addProxyProtocol(dq)) {
+ du->proxyProtocolPayloadSize = payloadSize;
+ }
}
int fd = pickBackendSocketForSending(du->downstream);
{
query = InternalQuery(std::move(du->query), std::move(du->ids));
downstream = du->downstream;
+ proxyProtocolPayloadSize = du->proxyProtocolPayloadSize;
}
~DoHCrossProtocolQuery()