From 3da5caaf943ce9ddc6ea2035686ea6f7c75a2a6e Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 8 Dec 2022 10:34:38 +0100 Subject: [PATCH] dnsreplay: Check early if IP_TRANSPARENT is working when requested --- pdns/dnsreplay.cc | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/pdns/dnsreplay.cc b/pdns/dnsreplay.cc index 3b6dc35d7a..48eaf8cca9 100644 --- a/pdns/dnsreplay.cc +++ b/pdns/dnsreplay.cc @@ -576,6 +576,22 @@ static void addECSOption(char* packet, const size_t packetSize, uint16_t* len, c } } +static bool checkIPTransparentUsability() +{ +#ifdef IP_TRANSPARENT + try { + auto s = Socket(SSocket(AF_INET, SOCK_DGRAM, 0)); + SSetsockopt(s.getHandle(), IPPROTO_IP , IP_TRANSPARENT, 1); + return true; + } + catch (const std::exception& e) { + cerr << "Error while checking whether IP_TRANSPARENT (required for '--source-from-pcap') is working properly: " << e.what() << endl; + } +#endif /* IP_TRANSPARENT */ + return false; +} + + static bool g_rdSelector; static uint16_t g_pcapDnsPort; @@ -615,11 +631,10 @@ static bool sendPacketFromPR(PcapPacketReader& pr, const ComboAddress& remote, i } #ifdef IP_TRANSPARENT if (usePCAPSourceIP) { - int s = SSocket(AF_INET, SOCK_DGRAM, 0); - SSetsockopt(s, IPPROTO_IP , IP_TRANSPARENT, 1); - SBind(s, pr.getSource()); - sendto(s, reinterpret_cast(pr.d_payload), dlen, 0, reinterpret_cast(&remote), remote.getSocklen()); - close(s); + auto s = Socket(SSocket(AF_INET, SOCK_DGRAM, 0)); + SSetsockopt(s.getHandle(), IPPROTO_IP , IP_TRANSPARENT, 1); + SBind(s.getHandle(), pr.getSource()); + sendto(s.getHandle(), reinterpret_cast(pr.d_payload), dlen, 0, reinterpret_cast(&remote), remote.getSocklen()); } else { #endif /* IP_TRANSPARENT */ @@ -674,17 +689,17 @@ static bool sendPacketFromPR(PcapPacketReader& pr, const ComboAddress& remote, i } } } - catch(const MOADNSException &mde) - { - if(!g_quiet) + catch (const MOADNSException& mde) { + if (!g_quiet) { cerr<<"Error parsing packet: "<()<<"', port "<()<(); + if (usePCAPSourceIP && !checkIPTransparentUsability()) { + cerr << "--source-from-pcap requested but IP_TRANSPARENT support is not working properly" << endl; + exit(EXIT_FAILURE); + } + unsigned int once=0; struct timeval mental_time; mental_time.tv_sec=0; mental_time.tv_usec=0; -- 2.47.2