• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

PowerDNS / pdns / 12595591960

03 Jan 2025 09:27AM UTC coverage: 62.774% (+2.5%) from 60.245%
12595591960

Pull #15008

github

web-flow
Merge c2a2749d3 into 788f396a7
Pull Request #15008: Do not follow CNAME records for ANY or CNAME queries

30393 of 78644 branches covered (38.65%)

Branch coverage included in aggregate %.

105822 of 138350 relevant lines covered (76.49%)

4613078.44 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.66
/pdns/pollmplexer.cc
1
#ifdef HAVE_CONFIG_H
2
#include "config.h"
3
#endif
4
#include "mplexer.hh"
5
#include "sstuff.hh"
6
#include <iostream>
7
#include <poll.h>
8
#include <unordered_map>
9
#include "misc.hh"
10
#include "namespaces.hh"
11

12
FDMultiplexer* FDMultiplexer::getMultiplexerSilent(unsigned int maxEventsHint)
13
{
4,928✔
14
  FDMultiplexer* ret = nullptr;
4,928✔
15
  for (const auto& i : FDMultiplexer::getMultiplexerMap()) {
4,933!
16
    try {
4,933✔
17
      ret = i.second(std::min(maxEventsHint, FDMultiplexer::s_maxevents));
4,933✔
18
      return ret;
4,933✔
19
    }
4,933✔
20
    catch (const FDMultiplexerException& fe) {
4,933✔
21
    }
5✔
22
    catch (...) {
4,933✔
23
    }
×
24
  }
4,933✔
25
  return ret;
×
26
}
4,928✔
27

28
class PollFDMultiplexer : public FDMultiplexer
29
{
30
public:
31
  PollFDMultiplexer(unsigned int /* maxEventsHint */)
32
  {}
15✔
33

34
  int run(struct timeval* tv, int timeout = 500) override;
35
  void getAvailableFDs(std::vector<int>& fds, int timeout) override;
36

37
  void addFD(int fd, FDMultiplexer::EventKind) override;
38
  void removeFD(int fd, FDMultiplexer::EventKind) override;
39

40
  string getName() const override
41
  {
×
42
    return "poll";
×
43
  }
×
44

45
private:
46
  std::unordered_map<int, struct pollfd> d_pollfds;
47
  vector<struct pollfd> preparePollFD() const;
48
};
49

50
static FDMultiplexer* make(unsigned int maxEventsHint)
51
{
15✔
52
  return new PollFDMultiplexer(maxEventsHint);
15✔
53
}
15✔
54

55
static struct RegisterOurselves
56
{
57
  RegisterOurselves()
58
  {
811✔
59
    FDMultiplexer::getMultiplexerMap().emplace(2, &make);
811✔
60
  }
811✔
61
} doIt;
62

63
static int convertEventKind(FDMultiplexer::EventKind kind)
64
{
35✔
65
  switch (kind) {
35!
66
  case FDMultiplexer::EventKind::Read:
10✔
67
    return POLLIN;
10✔
68
  case FDMultiplexer::EventKind::Write:
20✔
69
    return POLLOUT;
20✔
70
  case FDMultiplexer::EventKind::Both:
5✔
71
    return POLLIN | POLLOUT;
5✔
72
  }
35✔
73
  throw std::runtime_error("Unhandled event kind in the ports multiplexer");
×
74
}
35✔
75

76
void PollFDMultiplexer::addFD(int fd, FDMultiplexer::EventKind kind)
77
{
35✔
78
  if (d_pollfds.count(fd) == 0) {
35✔
79
    auto& pollfd = d_pollfds[fd];
30✔
80
    pollfd.fd = fd;
30✔
81
    pollfd.events = 0;
30✔
82
  }
30✔
83
  auto& pollfd = d_pollfds.at(fd);
35✔
84
  pollfd.events |= convertEventKind(kind);
35✔
85
}
35✔
86

87
void PollFDMultiplexer::removeFD(int fd, FDMultiplexer::EventKind)
88
{
30✔
89
  d_pollfds.erase(fd);
30✔
90
}
30✔
91

92
vector<struct pollfd> PollFDMultiplexer::preparePollFD() const
93
{
85✔
94
  std::vector<struct pollfd> result;
85✔
95
  result.reserve(d_pollfds.size());
85✔
96
  for (const auto& entry : d_pollfds) {
85✔
97
    result.push_back(entry.second);
75✔
98
  }
75✔
99

100
  return result;
85✔
101
}
85✔
102

103
void PollFDMultiplexer::getAvailableFDs(std::vector<int>& fds, int timeout)
104
{
45✔
105
  auto pollfds = preparePollFD();
45✔
106
  if (pollfds.empty()) {
45✔
107
    return;
10✔
108
  }
10✔
109

110
  int ret = poll(&pollfds[0], pollfds.size(), timeout);
35✔
111

112
  if (ret < 0 && errno != EINTR) {
35!
113
    throw FDMultiplexerException("poll returned error: " + stringerror());
×
114
  }
×
115

116
  for (const auto& pollfd : pollfds) {
40✔
117
    if (pollfd.revents & POLLIN || pollfd.revents & POLLOUT || pollfd.revents & POLLERR || pollfd.revents & POLLHUP) {
40!
118
      fds.push_back(pollfd.fd);
35✔
119
    }
35✔
120
  }
40✔
121
}
35✔
122

123
int PollFDMultiplexer::run(struct timeval* now, int timeout)
124
{
40✔
125
  InRun guard(d_inrun);
40✔
126

127
  auto pollfds = preparePollFD();
40✔
128
  if (pollfds.empty()) {
40✔
129
    gettimeofday(now, nullptr); // MANDATORY!
10✔
130
    return 0;
10✔
131
  }
10✔
132

133
  int ret = poll(&pollfds[0], pollfds.size(), timeout);
30✔
134
  gettimeofday(now, nullptr); // MANDATORY!
30✔
135

136
  if (ret < 0 && errno != EINTR) {
30!
137
    throw FDMultiplexerException("poll returned error: " + stringerror());
×
138
  }
×
139

140
  int count = 0;
30✔
141
  for (const auto& pollfd : pollfds) {
35✔
142
    if (pollfd.revents & POLLIN || pollfd.revents & POLLERR || pollfd.revents & POLLHUP) {
35!
143
      const auto& iter = d_readCallbacks.find(pollfd.fd);
15✔
144
      if (iter != d_readCallbacks.end()) {
15!
145
        iter->d_callback(iter->d_fd, iter->d_parameter);
15✔
146
        count++;
15✔
147
      }
15✔
148
    }
15✔
149

150
    if (pollfd.revents & POLLOUT || pollfd.revents & POLLERR) {
35!
151
      const auto& iter = d_writeCallbacks.find(pollfd.fd);
20✔
152
      if (iter != d_writeCallbacks.end()) {
20!
153
        iter->d_callback(iter->d_fd, iter->d_parameter);
20✔
154
        count++;
20✔
155
      }
20✔
156
    }
20✔
157
  }
35✔
158

159
  return count;
30✔
160
}
30✔
161

162
#if 0
163

164
void acceptData(int fd, boost::any& parameter)
165
{
166
  cout<<"Have data on fd "<<fd<<endl;
167
  Socket* sock=boost::any_cast<Socket*>(parameter);
168
  string packet;
169
  IPEndpoint rem;
170
  sock->recvFrom(packet, rem);
171
  cout<<"Received "<<packet.size()<<" bytes!\n";
172
}
173

174

175
int main()
176
{
177
  Socket s(AF_INET, SOCK_DGRAM);
178

179
  IPEndpoint loc("0.0.0.0", 2000);
180
  s.bind(loc);
181

182
  PollFDMultiplexer sfm;
183

184
  sfm.addReadFD(s.getHandle(), &acceptData, &s);
185

186
  for(int n=0; n < 100 ; ++n) {
187
    sfm.run();
188
  }
189
  sfm.removeReadFD(s.getHandle());
190
  sfm.removeReadFD(s.getHandle());
191
}
192
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc