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

PowerDNS / pdns / 14230500445

02 Apr 2025 01:53PM UTC coverage: 52.058% (-11.4%) from 63.455%
14230500445

push

github

web-flow
Merge pull request #15385 from rgacogne/ddist-enable-quiche-sni-tests

dnsdist: Enable the DoQ and DoH3 parts of the SNI tests in our CI

21502 of 68138 branches covered (31.56%)

Branch coverage included in aggregate %.

77059 of 121190 relevant lines covered (63.59%)

4345179.2 hits per line

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

88.1
/pdns/auth-zonecache.cc
1
/*
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
 */
22
#ifdef HAVE_CONFIG_H
23
#include "config.h"
24
#endif
25

26
#include "auth-zonecache.hh"
27
#include "logger.hh"
28
#include "statbag.hh"
29
#include "arguments.hh"
30
#include "cachecleaner.hh"
31
extern StatBag S;
32

33
AuthZoneCache::AuthZoneCache(size_t mapsCount) :
34
  d_maps(mapsCount)
35
{
12✔
36
  S.declare("zone-cache-hit", "Number of zone cache hits");
12✔
37
  S.declare("zone-cache-miss", "Number of zone cache misses");
12✔
38
  S.declare("zone-cache-size", "Number of entries in the zone cache", StatType::gauge);
12✔
39

40
  d_statnumhit = S.getPointer("zone-cache-hit");
12✔
41
  d_statnummiss = S.getPointer("zone-cache-miss");
12✔
42
  d_statnumentries = S.getPointer("zone-cache-size");
12✔
43
}
12✔
44

45
bool AuthZoneCache::getEntry(const DNSName& zone, int& zoneId)
46
{
4✔
47
  auto& mc = getMap(zone);
4✔
48
  bool found = false;
4✔
49
  {
4✔
50
    auto map = mc.d_map.read_lock();
4✔
51
    auto iter = map->find(zone);
4✔
52
    if (iter != map->end()) {
4✔
53
      found = true;
3✔
54
      zoneId = iter->second.zoneId;
3✔
55
    }
3✔
56
  }
4✔
57

58
  if (found) {
4✔
59
    (*d_statnumhit)++;
3✔
60
  }
3✔
61
  else {
1✔
62
    (*d_statnummiss)++;
1✔
63
  }
1✔
64
  return found;
4✔
65
}
4✔
66

67
bool AuthZoneCache::isEnabled() const
68
{
120✔
69
  return d_refreshinterval > 0;
120✔
70
}
120✔
71

72
void AuthZoneCache::clear()
73
{
25✔
74
  purgeLockedCollectionsVector(d_maps);
25✔
75
}
25✔
76

77
void AuthZoneCache::replace(const vector<std::tuple<DNSName, int>>& zone_indices)
78
{
4✔
79
  if (!d_refreshinterval)
4!
80
    return;
×
81

82
  size_t count = zone_indices.size();
4✔
83
  vector<cmap_t> newMaps(d_maps.size());
4✔
84

85
  // build new maps
86
  for (const auto& [zone, id] : zone_indices) {
5✔
87
    CacheValue val;
5✔
88
    val.zoneId = id;
5✔
89
    auto& mc = newMaps[getMapIndex(zone)];
5✔
90
    auto iter = mc.find(zone);
5✔
91
    if (iter != mc.end()) {
5!
92
      iter->second = val;
×
93
    }
×
94
    else {
5✔
95
      mc.emplace(zone, val);
5✔
96
    }
5✔
97
  }
5✔
98

99
  {
4✔
100
    // process zone updates done while data collection for replace() was already in progress.
101
    auto pending = d_pending.lock();
4✔
102
    assert(pending->d_replacePending); // make sure we never forget to call setReplacePending()
4✔
103
    for (const auto& [zone, id, insert] : pending->d_pendingUpdates) {
3✔
104
      CacheValue val;
3✔
105
      val.zoneId = id;
3✔
106
      auto& mc = newMaps[getMapIndex(zone)];
3✔
107
      auto iter = mc.find(zone);
3✔
108
      if (iter != mc.end()) {
3✔
109
        if (insert) {
2✔
110
          iter->second = val;
1✔
111
        }
1✔
112
        else {
1✔
113
          mc.erase(iter);
1✔
114
          count--;
1✔
115
        }
1✔
116
      }
2✔
117
      else if (insert) {
1!
118
        mc.emplace(zone, val);
1✔
119
        count++;
1✔
120
      }
1✔
121
    }
3✔
122

123
    for (size_t mapIndex = 0; mapIndex < d_maps.size(); mapIndex++) {
4,100✔
124
      auto& mc = d_maps[mapIndex];
4,096✔
125
      auto map = mc.d_map.write_lock();
4,096✔
126
      *map = std::move(newMaps[mapIndex]);
4,096✔
127
    }
4,096✔
128

129
    pending->d_pendingUpdates.clear();
4✔
130
    pending->d_replacePending = false;
4✔
131

132
    d_statnumentries->store(count);
4✔
133
  }
4✔
134
}
4✔
135

136
void AuthZoneCache::add(const DNSName& zone, const int zoneId)
137
{
2✔
138
  if (!d_refreshinterval)
2!
139
    return;
×
140

141
  {
2✔
142
    auto pending = d_pending.lock();
2✔
143
    if (pending->d_replacePending) {
2!
144
      pending->d_pendingUpdates.emplace_back(zone, zoneId, true);
2✔
145
    }
2✔
146
  }
2✔
147

148
  CacheValue val;
2✔
149
  val.zoneId = zoneId;
2✔
150

151
  int mapIndex = getMapIndex(zone);
2✔
152
  {
2✔
153
    auto& mc = d_maps[mapIndex];
2✔
154
    auto map = mc.d_map.write_lock();
2✔
155
    auto iter = map->find(zone);
2✔
156
    if (iter != map->end()) {
2!
157
      iter->second = val;
×
158
    }
×
159
    else {
2✔
160
      map->emplace(zone, val);
2✔
161
      (*d_statnumentries)++;
2✔
162
    }
2✔
163
  }
2✔
164
}
2✔
165

166
void AuthZoneCache::remove(const DNSName& zone)
167
{
1✔
168
  if (!d_refreshinterval)
1!
169
    return;
×
170

171
  {
1✔
172
    auto pending = d_pending.lock();
1✔
173
    if (pending->d_replacePending) {
1!
174
      pending->d_pendingUpdates.emplace_back(zone, -1, false);
1✔
175
    }
1✔
176
  }
1✔
177

178
  int mapIndex = getMapIndex(zone);
1✔
179
  {
1✔
180
    auto& mc = d_maps[mapIndex];
1✔
181
    auto map = mc.d_map.write_lock();
1✔
182
    if (map->erase(zone)) {
1!
183
      (*d_statnumentries)--;
×
184
    }
×
185
  }
1✔
186
}
1✔
187

188
void AuthZoneCache::setReplacePending()
189
{
4✔
190
  if (!d_refreshinterval)
4!
191
    return;
×
192

193
  {
4✔
194
    auto pending = d_pending.lock();
4✔
195
    pending->d_replacePending = true;
4✔
196
    pending->d_pendingUpdates.clear();
4✔
197
  }
4✔
198
}
4✔
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

© 2026 Coveralls, Inc