]>
Commit | Line | Data |
---|---|---|
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 |
42 | void 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 | 60 | void 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 |
76 | void 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 | |
106 | void 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 |