]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/communicator.cc
rec: ensure correct service user on debian
[thirdparty/pdns.git] / pdns / communicator.cc
CommitLineData
12c86877 1/*
12471842
PL
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * In addition, for the avoidance of any doubt, permission is granted to
10 * link this program with OpenSSL and to (re)distribute the binaries
11 * produced as the result of such linking.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
870a0fe4
AT
22#ifdef HAVE_CONFIG_H
23#include "config.h"
24#endif
379ab445 25#include "packetcache.hh"
12c86877
BH
26#include "utility.hh"
27#include <errno.h>
28#include "communicator.hh"
29#include <set>
4232a932 30#include <boost/utility.hpp>
12c86877
BH
31#include "dnsbackend.hh"
32#include "ueberbackend.hh"
33#include "packethandler.hh"
34#include "resolver.hh"
35#include "logger.hh"
36#include "dns.hh"
37#include "arguments.hh"
13597144 38#include "packetcache.hh"
519f5484 39#include "threadname.hh"
02b37061 40
3e7dcee6 41// there can be MANY OF THESE
dbcb3066
BH
42void CommunicatorClass::retrievalLoopThread(void)
43{
519f5484 44 setThreadName("pdns/comm-retre");
dbcb3066
BH
45 for(;;) {
46 d_suck_sem.wait();
47 SuckRequest sr;
48 {
49 Lock l(&d_lock);
50 if(d_suckdomains.empty())
f2d26033 51 continue;
232f0877 52
dbcb3066 53 sr=d_suckdomains.front();
f4ce804f 54 d_suckdomains.pop_front();
dbcb3066 55 }
d3ee36f2 56 suck(sr.domain, sr.master);
dbcb3066
BH
57 }
58}
59
e8940583 60void CommunicatorClass::loadArgsIntoSet(const char *listname, set<string> &listset)
d702c27f
RC
61{
62 vector<string> parts;
63 stringtok(parts, ::arg()[listname], ", \t");
64 for (vector<string>::const_iterator iter = parts.begin(); iter != parts.end(); ++iter) {
65 try {
66 ComboAddress caIp(*iter, 53);
67 listset.insert(caIp.toStringWithPort());
68 }
69 catch(PDNSException &e) {
e6a9dde5 70 g_log<<Logger::Error<<"Unparseable IP in "<<listname<<". Error: "<<e.reason<<endl;
5bd2ea7b 71 _exit(1);
d702c27f
RC
72 }
73 }
74}
75
dbcb3066
BH
76void CommunicatorClass::go()
77{
d207ad63
RK
78 try {
79 PacketHandler::s_allowNotifyFrom.toMasks(::arg()["allow-notify-from"] );
80 }
81 catch(PDNSException &e) {
e6a9dde5 82 g_log<<Logger::Error<<"Unparseable IP in allow-notify-from. Error: "<<e.reason<<endl;
5bd2ea7b 83 _exit(1);
d207ad63
RK
84 }
85
dbcb3066 86 pthread_t tid;
a71bee29 87 pthread_create(&tid,0,&launchhelper,this); // Starts CommunicatorClass::mainloop()
ff99a74b 88 for(int n=0; n < ::arg().asNum("retrieval-threads", 1); ++n)
a71bee29 89 pthread_create(&tid, 0, &retrieveLaunchhelper, this); // Starts CommunicatorClass::retrievalLoopThread()
dbcb3066 90
68bb0e57 91 d_preventSelfNotification = ::arg().mustDo("prevent-self-notification");
79a454ef
KM
92
93 try {
94 d_onlyNotify.toMasks(::arg()["only-notify"]);
95 }
96 catch(PDNSException &e) {
e6a9dde5 97 g_log<<Logger::Error<<"Unparseable IP in only-notify. Error: "<<e.reason<<endl;
5bd2ea7b 98 _exit(1);
79a454ef 99 }
24d3239e 100
e8940583 101 loadArgsIntoSet("also-notify", d_alsoNotify);
dad0736b 102
e8940583 103 loadArgsIntoSet("forward-notify", PacketHandler::s_forwardNotify);
dbcb3066 104}
12c86877
BH
105
106void CommunicatorClass::mainloop(void)
107{
108 try {
519f5484 109 setThreadName("pdns/comm-main");
12c86877 110 signal(SIGPIPE,SIG_IGN);
e6a9dde5 111 g_log<<Logger::Error<<"Master/slave communicator launching"<<endl;
12c86877 112 PacketHandler P;
379ab445 113 d_tickinterval=::arg().asNum("slave-cycle-interval");
0c01dd7c 114 makeNotifySockets();
12c86877 115
006adf32
OM
116 int rc;
117 time_t next, tick;
118
3e76cf5f 119 for(;;) {
12c86877
BH
120 slaveRefresh(&P);
121 masterUpdateCheck(&P);
006adf32
OM
122 tick=doNotifications(); // this processes any notification acknowledgements and actually send out our own notifications
123
124 tick = min (tick, d_tickinterval);
125
126 next=time(0)+tick;
12c86877 127
006adf32
OM
128 while(time(0) < next) {
129 rc=d_any_sem.tryWait();
12c86877 130
006adf32 131 if(rc) {
3e76cf5f 132 bool extraSlaveRefresh = false;
006adf32 133 Utility::sleep(1);
3e76cf5f
OM
134 {
135 Lock l(&d_lock);
136 if (d_tocheck.size())
137 extraSlaveRefresh = true;
138 }
139 if (extraSlaveRefresh)
140 slaveRefresh(&P);
141 }
142 else {
006adf32
OM
143 // eat up extra posts to avoid busy looping if many posts were done
144 while (d_any_sem.tryWait() == 0) {
145 }
3e76cf5f
OM
146 break; // something happened
147 }
148 // this gets executed at least once every second
149 doNotifications();
12c86877
BH
150 }
151 }
152 }
3f81d239 153 catch(PDNSException &ae) {
e6a9dde5 154 g_log<<Logger::Error<<"Exiting because communicator thread died with error: "<<ae.reason<<endl;
ac2bb9e7 155 Utility::sleep(1);
5bd2ea7b 156 _exit(1);
12c86877 157 }
0c70797e 158 catch(std::exception &e) {
e6a9dde5 159 g_log<<Logger::Error<<"Exiting because communicator thread died with STL error: "<<e.what()<<endl;
5bd2ea7b 160 _exit(1);
12c86877
BH
161 }
162 catch( ... )
163 {
e6a9dde5 164 g_log << Logger::Error << "Exiting because communicator caught unknown exception." << endl;
5bd2ea7b 165 _exit(1);
12c86877
BH
166 }
167}
168