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

PowerDNS / pdns / 19741624072

27 Nov 2025 03:45PM UTC coverage: 73.086% (+0.02%) from 73.065%
19741624072

Pull #16570

github

web-flow
Merge 08a2cdb1d into f94a3f63f
Pull Request #16570: rec: rewrite all unwrap calls in web.rs

38523 of 63408 branches covered (60.75%)

Branch coverage included in aggregate %.

128044 of 164496 relevant lines covered (77.84%)

6531485.83 hits per line

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

77.78
/pdns/dnsdistdist/dnsdist-lbpolicies.hh
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
#pragma once
23

24
#include <memory>
25
#include <optional>
26

27
struct dnsdist_ffi_servers_list_t;
28
struct dnsdist_ffi_server_t;
29
struct dnsdist_ffi_dnsquestion_t;
30

31
struct DNSQuestion;
32
struct DownstreamState;
33

34
struct PerThreadPoliciesState;
35

36
class ServerPolicy
37
{
38
public:
39
  using SelectedServerPosition = unsigned int;
40
  template <class T>
41
  using Numbered = std::pair<unsigned int, T>;
42
  using NumberedServer = Numbered<std::shared_ptr<DownstreamState>>;
43
  template <class T>
44
  using NumberedVector = std::vector<std::pair<unsigned int, T>>;
45
  using NumberedServerVector = NumberedVector<std::shared_ptr<DownstreamState>>;
46
  using policyfunc_t = std::function<std::optional<SelectedServerPosition>(const NumberedServerVector& servers, const DNSQuestion*)>;
47
  using ffipolicyfunc_t = std::function<SelectedServerPosition(dnsdist_ffi_servers_list_t* servers, dnsdist_ffi_dnsquestion_t* dq)>;
48

49
  ServerPolicy(const std::string& name_, policyfunc_t policy_, bool isLua_) :
50
    d_name(name_), d_policy(std::move(policy_)), d_isLua(isLua_)
6,523✔
51
  {
6,523✔
52
  }
6,523✔
53

54
  ServerPolicy(const std::string& name_, ffipolicyfunc_t policy_) :
55
    d_name(name_), d_ffipolicy(std::move(policy_)), d_isLua(true), d_isFFI(true)
2✔
56
  {
2✔
57
  }
2✔
58

59
  /* create a per-thread FFI policy */
60
  ServerPolicy(const std::string& name_, const std::string& code);
61

62
  ServerPolicy()
63
  {
805✔
64
  }
805✔
65

66
  class SelectedBackend
67
  {
68
  public:
69
    SelectedBackend(const NumberedServerVector& backends) :
70
      d_backends(&backends)
14,256✔
71
    {
14,256✔
72
    }
14,256✔
73

74
    void setSelected(SelectedServerPosition selected)
75
    {
8,325✔
76
      if (selected >= d_backends->size()) {
8,325!
77
        throw std::runtime_error("Setting an invalid backend position (" + std::to_string(selected) + " out of " + std::to_string(d_backends->size()) + ") from the server policy");
×
78
      }
×
79
      d_selected = selected;
8,325✔
80
    }
8,325✔
81

82
    operator bool() const noexcept
83
    {
32,030✔
84
      return d_selected.has_value();
32,030✔
85
    }
32,030✔
86

87
    DownstreamState* operator->() const
88
    {
20,462✔
89
      return (*d_backends)[*d_selected].second.get();
20,462✔
90
    }
20,462✔
91

92
    const std::shared_ptr<DownstreamState>& get() const
93
    {
8,323✔
94
      return (*d_backends)[*d_selected].second;
8,323✔
95
    }
8,323✔
96

97
  private:
98
    const NumberedServerVector* d_backends{nullptr};
99
    std::optional<SelectedServerPosition> d_selected{std::nullopt};
100
  };
101

102
  SelectedBackend getSelectedBackend(const ServerPolicy::NumberedServerVector& servers, DNSQuestion& dnsQuestion) const;
103

104
  const std::string& getName() const
105
  {
418✔
106
    return d_name;
418✔
107
  }
418✔
108

109
  std::string toString() const
110
  {
×
111
    return std::string("ServerPolicy") + (d_isLua ? " (Lua)" : "") + " \"" + d_name + "\"";
×
112
  }
×
113

114
private:
115
  struct PerThreadState;
116

117
  const ffipolicyfunc_t& getPerThreadPolicy() const;
118
  static thread_local std::unique_ptr<PerThreadState> t_perThreadState;
119

120
public:
121
  std::string d_name;
122
  std::string d_perThreadPolicyCode;
123

124
  policyfunc_t d_policy;
125
  ffipolicyfunc_t d_ffipolicy;
126

127
  bool d_isLua{false};
128
  bool d_isFFI{false};
129
  bool d_isPerThread{false};
130
};
131

132
struct ServerPool;
133

134
using pools_t = std::map<std::string, std::shared_ptr<ServerPool>>;
135
const ServerPool& getPool(const std::string& poolName);
136
const ServerPool& createPoolIfNotExists(const std::string& poolName);
137
void setPoolPolicy(const std::string& poolName, std::shared_ptr<ServerPolicy> policy);
138
void addServerToPool(const std::string& poolName, std::shared_ptr<DownstreamState> server);
139
void removeServerFromPool(const std::string& poolName, std::shared_ptr<DownstreamState> server);
140

141
const ServerPolicy::NumberedServerVector& getDownstreamCandidates(const std::string& poolName);
142

143
std::optional<ServerPolicy::SelectedServerPosition> firstAvailable(const ServerPolicy::NumberedServerVector& servers, const DNSQuestion* dnsQuestion);
144
std::optional<ServerPolicy::SelectedServerPosition> leastOutstanding(const ServerPolicy::NumberedServerVector& servers, const DNSQuestion* dnsQuestion);
145
std::optional<ServerPolicy::SelectedServerPosition> wrandom(const ServerPolicy::NumberedServerVector& servers, const DNSQuestion* dnsQuestion);
146
std::optional<ServerPolicy::SelectedServerPosition> whashed(const ServerPolicy::NumberedServerVector& servers, const DNSQuestion* dnsQuestion);
147
std::optional<ServerPolicy::SelectedServerPosition> whashedFromHash(const ServerPolicy::NumberedServerVector& servers, size_t hash);
148
std::optional<ServerPolicy::SelectedServerPosition> chashed(const ServerPolicy::NumberedServerVector& servers, const DNSQuestion* dnsQuestion);
149
std::optional<ServerPolicy::SelectedServerPosition> chashedFromHash(const ServerPolicy::NumberedServerVector& servers, size_t hash);
150
std::optional<ServerPolicy::SelectedServerPosition> roundrobin(const ServerPolicy::NumberedServerVector& servers, const DNSQuestion* dnsQuestion);
151
std::optional<ServerPolicy::SelectedServerPosition> orderedWrandUntag(const ServerPolicy::NumberedServerVector& servers, const DNSQuestion* dnsQuestion);
152

153
#include <unordered_map>
154

155
namespace dnsdist::lbpolicies
156
{
157
const std::vector<std::shared_ptr<ServerPolicy>>& getBuiltInPolicies();
158
}
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