#ifdef HAVE_PROTOBUF
boost::uuids::random_generator uuidGenerator;
#endif
+#ifdef HAVE_DNSCRYPT
+ /* when the answer is encrypted in place, we need to get a copy
+ of the original header before encryption to fill the ring buffer */
+ dnsheader dhCopy;
+#endif
map<ComboAddress,int> sockets;
for(;;) {
if(dq.dh->qr) { // something turned it into a response
restoreFlags(dh, origFlags);
#ifdef HAVE_DNSCRYPT
- if (!encryptResponse(queryBuffer, &dq.len, dq.size, true, dnsCryptQuery)) {
+ if (!encryptResponse(queryBuffer, &dq.len, dq.size, true, dnsCryptQuery, nullptr, nullptr)) {
goto drop;
}
#endif
}
#ifdef HAVE_DNSCRYPT
- if (!encryptResponse(cachedResponse, &cachedResponseSize, sizeof cachedResponse, true, dnsCryptQuery)) {
+ if (!encryptResponse(cachedResponse, &cachedResponseSize, sizeof cachedResponse, true, dnsCryptQuery, nullptr, nullptr)) {
goto drop;
}
#endif
dq.dh->qr = true;
#ifdef HAVE_DNSCRYPT
- if (!encryptResponse(queryBuffer, &dq.len, dq.size, true, dnsCryptQuery)) {
+ if (!encryptResponse(queryBuffer, &dq.len, dq.size, true, dnsCryptQuery, nullptr, nullptr)) {
goto drop;
}
#endif
}
#ifdef HAVE_DNSCRYPT
- if (!encryptResponse(response, &responseLen, responseSize, true, dnsCryptQuery)) {
+ if (!encryptResponse(response, &responseLen, responseSize, true, dnsCryptQuery, &dh, &dhCopy)) {
goto drop;
}
#endif
}
#ifdef HAVE_DNSCRYPT
-bool encryptResponse(char* response, uint16_t* responseLen, size_t responseSize, bool tcp, std::shared_ptr<DnsCryptQuery> dnsCryptQuery)
+bool encryptResponse(char* response, uint16_t* responseLen, size_t responseSize, bool tcp, std::shared_ptr<DnsCryptQuery> dnsCryptQuery, dnsheader** dh, dnsheader* dhCopy)
{
if (dnsCryptQuery) {
uint16_t encryptedResponseLen = 0;
+
+ /* save the original header before encrypting it in place */
+ if (dh != nullptr && *dh != nullptr && dhCopy != nullptr) {
+ memcpy(dhCopy, *dh, sizeof(dnsheader));
+ *dh = dhCopy;
+ }
+
int res = dnsCryptQuery->ctx->encryptResponse(response, *responseLen, responseSize, dnsCryptQuery, tcp, &encryptedResponseLen);
if (res == 0) {
*responseLen = encryptedResponseLen;
auto localRespRulactions = g_resprulactions.getLocal();
#ifdef HAVE_DNSCRYPT
char packet[4096 + DNSCRYPT_MAX_RESPONSE_PADDING_AND_MAC_SIZE];
+ /* when the answer is encrypted in place, we need to get a copy
+ of the original header before encryption to fill the ring buffer */
+ dnsheader dhCopy;
#else
char packet[4096];
#endif
static_assert(sizeof(packet) <= UINT16_MAX, "Packet size should fit in a uint16_t");
vector<uint8_t> rewrittenResponse;
- struct dnsheader* dh = (struct dnsheader*)packet;
uint16_t queryId = 0;
for(;;) {
+ dnsheader* dh = reinterpret_cast<struct dnsheader*>(packet);
try {
ssize_t got = recv(state->fd, packet, sizeof(packet), 0);
char * response = packet;
if (ids->cs && !ids->cs->muted) {
#ifdef HAVE_DNSCRYPT
- if (!encryptResponse(response, &responseLen, responseSize, false, ids->dnsCryptQuery)) {
+ if (!encryptResponse(response, &responseLen, responseSize, false, ids->dnsCryptQuery, &dh, &dhCopy)) {
continue;
}
#endif
if (!cs->muted) {
#ifdef HAVE_DNSCRYPT
- if (!encryptResponse(response, &responseLen, dq.size, false, dnsCryptQuery)) {
+ if (!encryptResponse(response, &responseLen, dq.size, false, dnsCryptQuery, nullptr, nullptr)) {
continue;
}
#endif
if (!cs->muted) {
#ifdef HAVE_DNSCRYPT
- if (!encryptResponse(cachedResponse, &cachedResponseSize, sizeof cachedResponse, false, dnsCryptQuery)) {
+ if (!encryptResponse(cachedResponse, &cachedResponseSize, sizeof cachedResponse, false, dnsCryptQuery, nullptr, nullptr)) {
continue;
}
#endif
dq.dh->qr = true;
#ifdef HAVE_DNSCRYPT
- if (!encryptResponse(response, &responseLen, dq.size, false, dnsCryptQuery)) {
+ if (!encryptResponse(response, &responseLen, dq.size, false, dnsCryptQuery, nullptr, nullptr)) {
continue;
}
#endif
extern std::vector<std::tuple<ComboAddress,DnsCryptContext,bool,int, std::string>> g_dnsCryptLocals;
int handleDnsCryptQuery(DnsCryptContext* ctx, char* packet, uint16_t len, std::shared_ptr<DnsCryptQuery>& query, uint16_t* decryptedQueryLen, bool tcp, std::vector<uint8_t>& response);
-bool encryptResponse(char* response, uint16_t* responseLen, size_t responseSize, bool tcp, std::shared_ptr<DnsCryptQuery> dnsCryptQuery);
+bool encryptResponse(char* response, uint16_t* responseLen, size_t responseSize, bool tcp, std::shared_ptr<DnsCryptQuery> dnsCryptQuery, dnsheader** dh, dnsheader* dhCopy);
#endif
#include "dnsdist-snmp.hh"