]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/dumresp.cc
Merge pull request #3802 from Habbie/robust-doresolve
[thirdparty/pdns.git] / pdns / dumresp.cc
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4 #include "iputils.hh"
5 #include "sstuff.hh"
6 #include "statbag.hh"
7 #include <atomic>
8 #include <sys/mman.h>
9 #include <thread>
10 StatBag S;
11
12 std::atomic<uint64_t>* g_counter;
13
14 void printStatus()
15 {
16 auto prev= g_counter->load();
17 for(;;) {
18 sleep(1);
19 cout<<g_counter->load()-prev<<"\t"<<g_counter->load()<<endl;
20 prev=g_counter->load();
21 }
22 }
23
24 void usage() {
25 cerr<<"Syntax: dumresp LOCAL-ADDRESS LOCAL-PORT NUMBER-OF-PROCESSES"<<endl;
26 }
27
28 int main(int argc, char** argv)
29 try
30 {
31 for(int i = 1; i < argc; i++) {
32 if((string) argv[i] == "--help"){
33 usage();
34 return(EXIT_SUCCESS);
35 }
36
37 if((string) argv[i] == "--version"){
38 cerr<<"dumresp "<<VERSION<<endl;
39 return(EXIT_SUCCESS);
40 }
41 }
42
43 if(argc != 4) {
44 usage();
45 exit(EXIT_FAILURE);
46 }
47
48 auto ptr = mmap(NULL, sizeof(std::atomic<uint64_t>), PROT_READ | PROT_WRITE,
49 MAP_SHARED | MAP_ANONYMOUS, -1, 0);
50
51 g_counter = new(ptr) std::atomic<uint64_t>();
52
53 int i=1;
54 for(; i < atoi(argv[3]); ++i) {
55 if(!fork())
56 break;
57 }
58 if(i==1) {
59 std::thread t(printStatus);
60 t.detach();
61 }
62
63 ComboAddress local(argv[1], atoi(argv[2]));
64 Socket s(local.sin4.sin_family, SOCK_DGRAM);
65 #ifdef SO_REUSEPORT
66 int one=1;
67 if(setsockopt(s.getHandle(), SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) < 0)
68 unixDie("setsockopt for REUSEPORT");
69 #endif
70
71 s.bind(local);
72 cout<<"Bound to "<<local.toStringWithPort()<<endl;
73 char buffer[1500];
74 struct dnsheader* dh = (struct dnsheader*)buffer;
75 int len;
76 ComboAddress rem=local;
77 socklen_t socklen = rem.getSocklen();
78 for(;;) {
79 len=recvfrom(s.getHandle(), buffer, sizeof(buffer), 0, (struct sockaddr*)&rem, &socklen);
80 (*g_counter)++;
81 if(len < 0)
82 unixDie("recvfrom");
83
84 if(dh->qr)
85 continue;
86 dh->qr=1;
87 dh->ad=0;
88 if(sendto(s.getHandle(), buffer, len, 0, (struct sockaddr*)&rem, socklen) < 0)
89 unixDie("sendto");
90
91 }
92 }
93 catch(std::exception& e)
94 {
95 cerr<<"Fatal error: "<<e.what()<<endl;
96 exit(EXIT_FAILURE);
97 }