}
}
+static void editPayloadID(PacketBuffer& payload, uint16_t newId, size_t proxyProtocolPayloadSize, bool sizePrepended)
+{
+ /* we cannot do a direct cast as the alignment might be off (the size of the payload might have been prepended, which is bad enough,
+ but we might also have a proxy protocol payload */
+ size_t startOfHeaderOffset = (sizePrepended ? sizeof(uint16_t) : 0) + proxyProtocolPayloadSize;
+ if (payload.size() < startOfHeaderOffset + sizeof(dnsheader)) {
+ throw std::runtime_error("Invalid buffer for outgoing TCP query (size " + std::to_string(payload.size()));
+ }
+ dnsheader dh;
+ memcpy(&dh, &payload.at(startOfHeaderOffset), sizeof(dh));
+ dh.id = htons(newId);
+ memcpy(&payload.at(startOfHeaderOffset), &dh, sizeof(dh));
+}
+
IOState TCPConnectionToBackend::queueNextQuery(std::shared_ptr<TCPConnectionToBackend>& conn)
{
conn->d_currentQuery = std::move(conn->d_pendingQueries.front());
- dnsheader* dh = reinterpret_cast<dnsheader*>(&conn->d_currentQuery.d_query.d_buffer.at(sizeof(uint16_t) + (conn->d_currentQuery.d_query.d_proxyProtocolPayloadAdded ? conn->d_currentQuery.d_query.d_proxyProtocolPayload.size() : 0)));
+
uint16_t id = conn->d_highestStreamID;
- dh->id = htons(id);
+ editPayloadID(conn->d_currentQuery.d_query.d_buffer, id, conn->d_currentQuery.d_query.d_proxyProtocolPayloadAdded ? conn->d_currentQuery.d_query.d_proxyProtocolPayload.size() : 0, true);
+
conn->d_pendingQueries.pop_front();
conn->d_state = State::sendingQueryToBackend;
conn->d_currentPos = 0;
if (conn->d_state == State::sendingQueryToBackend) {
/* we need to edit this query so it has the correct ID */
auto query = std::move(conn->d_currentQuery);
- dnsheader* dh = reinterpret_cast<dnsheader*>(&query.d_query.d_buffer.at(sizeof(uint16_t) + (query.d_query.d_proxyProtocolPayloadAdded ? query.d_query.d_proxyProtocolPayload.size() : 0)));
+
uint16_t id = conn->d_highestStreamID;
- dh->id = htons(id);
+ editPayloadID(query.d_query.d_buffer, id, query.d_query.d_proxyProtocolPayloadAdded ? query.d_query.d_proxyProtocolPayload.size() : 0, true);
conn->d_currentQuery = std::move(query);
}
DEBUGLOG("Sending new query to backend right away, with ID "<<d_highestStreamID);
d_state = State::sendingQueryToBackend;
d_currentPos = 0;
- dnsheader* dh = reinterpret_cast<dnsheader*>(&query.d_buffer.at(sizeof(uint16_t) + (query.d_proxyProtocolPayloadAdded ? query.d_proxyProtocolPayload.size() : 0)));
+
uint16_t id = d_highestStreamID;
- dh->id = htons(id);
+ editPayloadID(query.d_buffer, id, query.d_proxyProtocolPayloadAdded ? query.d_proxyProtocolPayload.size() : 0, true);
+
d_currentQuery = PendingRequest({sender, std::move(query)});
if (needProxyProtocolPayload() && !d_currentQuery.d_query.d_proxyProtocolPayloadAdded && !d_currentQuery.d_query.d_proxyProtocolPayload.empty()) {
return IOState::Done;
}
- auto dh = reinterpret_cast<dnsheader*>(d_responseBuffer.data());
- dh->id = it->second.d_query.d_idstate.origID;
+ editPayloadID(d_responseBuffer, ntohs(it->second.d_query.d_idstate.origID), 0, false);
auto sender = it->second.d_sender;
static void appendPayloadEditingID(PacketBuffer& buffer, const PacketBuffer& payload, uint16_t newID)
{
PacketBuffer newPayload(payload);
- auto dh = reinterpret_cast<dnsheader*>(&newPayload.at(sizeof(uint16_t)));
- dh->id = htons(newID);
+ dnsheader dh;
+ memcpy(&dh, &newPayload.at(sizeof(uint16_t)), sizeof(dh));
+ dh.id = htons(newID);
+ memcpy(&newPayload.at(sizeof(uint16_t)), &dh, sizeof(dh));
buffer.insert(buffer.end(), newPayload.begin(), newPayload.end());
}
static void prependPayloadEditingID(PacketBuffer& buffer, const PacketBuffer& payload, uint16_t newID)
{
PacketBuffer newPayload(payload);
- auto dh = reinterpret_cast<dnsheader*>(&newPayload.at(sizeof(uint16_t)));
- dh->id = htons(newID);
+ dnsheader dh;
+ memcpy(&dh, &newPayload.at(sizeof(uint16_t)), sizeof(dh));
+ dh.id = htons(newID);
+ memcpy(&newPayload.at(sizeof(uint16_t)), &dh, sizeof(dh));
buffer.insert(buffer.begin(), newPayload.begin(), newPayload.end());
}