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

PowerDNS / pdns / 19765062687

28 Nov 2025 01:22PM UTC coverage: 73.135% (+0.03%) from 73.105%
19765062687

Pull #16574

github

web-flow
Merge cc585a1f8 into 8b4e32eff
Pull Request #16574: Improve GitHub error highlighting

38564 of 63428 branches covered (60.8%)

Branch coverage included in aggregate %.

128155 of 164534 relevant lines covered (77.89%)

6255827.11 hits per line

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

79.53
/pdns/recursordist/rec-tcpout.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

23
#include "rec-tcpout.hh"
24

25
// This line from /usr/include/openssl/ssl2.h: # define CERT char
26
// throws dnsrecords.hh off the rails.
27
#undef CERT
28

29
#include "syncres.hh"
30
#include "dnsname.hh"
31
#include "rec-main.hh"
32

33
#include "cxxsettings.hh"
34

35
timeval TCPOutConnectionManager::s_maxIdleTime;
36
size_t TCPOutConnectionManager::s_maxQueries;
37
size_t TCPOutConnectionManager::s_maxIdlePerAuth;
38
size_t TCPOutConnectionManager::s_maxIdlePerThread;
39

40
void TCPOutConnectionManager::cleanup(const struct timeval& now)
41
{
748✔
42
  if (s_maxIdleTime.tv_sec == 0 && s_maxIdleTime.tv_usec == 0) {
748!
43
    // no maximum idle time
44
    return;
×
45
  }
×
46

47
  for (auto it = d_idle_connections.begin(); it != d_idle_connections.end();) {
749✔
48
    timeval idle = now - it->second.d_last_used;
1✔
49
    if (s_maxIdleTime < idle) {
1!
50
      it = d_idle_connections.erase(it);
×
51
    }
×
52
    else {
1✔
53
      ++it;
1✔
54
    }
1✔
55
  }
1✔
56
}
748✔
57

58
void TCPOutConnectionManager::store(const struct timeval& now, const endpoints_t& endpoints, Connection&& connection)
59
{
31✔
60
  ++connection.d_numqueries;
31✔
61
  if (s_maxQueries > 0 && connection.d_numqueries >= s_maxQueries) {
31!
62
    return;
×
63
  }
×
64

65
  if (d_idle_connections.size() >= s_maxIdlePerThread || d_idle_connections.count(endpoints) >= s_maxIdlePerAuth) {
31!
66
    cleanup(now);
×
67
  }
×
68

69
  if (d_idle_connections.size() >= s_maxIdlePerThread) {
31!
70
    return;
×
71
  }
×
72
  if (d_idle_connections.count(endpoints) >= s_maxIdlePerAuth) {
31!
73
    return;
×
74
  }
×
75

76
  gettimeofday(&connection.d_last_used, nullptr);
31✔
77
  d_idle_connections.emplace(endpoints, std::move(connection));
31✔
78
}
31✔
79

80
TCPOutConnectionManager::Connection TCPOutConnectionManager::get(const endpoints_t& pair)
81
{
35✔
82
  if (d_idle_connections.count(pair) > 0) {
35✔
83
    auto connection = d_idle_connections.extract(pair);
10✔
84
    return connection.mapped();
10✔
85
  }
10✔
86
  return Connection{};
25✔
87
}
35✔
88

89
struct OutgoingTLSConfigTable
90
{
91
  SuffixMatchTree<pdns::rust::settings::rec::OutgoingTLSConfiguration> d_suffixToConfig;
92
  NetmaskTree<pdns::rust::settings::rec::OutgoingTLSConfiguration> d_netmaskToConfig;
93
};
94

95
static LockGuarded<OutgoingTLSConfigTable> s_outgoingTLSConfigTable;
96

97
void TCPOutConnectionManager::setupOutgoingTLSConfigTables(pdns::rust::settings::rec::Recursorsettings& settings)
98
{
23✔
99
  auto& vec = settings.outgoing.tls_configurations;
23✔
100
  auto table = s_outgoingTLSConfigTable.lock();
23✔
101
  table->d_suffixToConfig = SuffixMatchTree<pdns::rust::settings::rec::OutgoingTLSConfiguration>(); // no clear?
23✔
102
  table->d_netmaskToConfig.clear();
23✔
103
  for (const auto& entry : vec) {
23✔
104
    for (const auto& element : entry.suffixes) {
8✔
105
      DNSName name = DNSName(std::string(element));
2✔
106
      auto copy = entry;
2✔
107
      table->d_suffixToConfig.add(name, std::move(copy));
2✔
108
    }
2✔
109
    for (const auto& element : entry.subnets) {
8✔
110
      table->d_netmaskToConfig.insert(std::string(element)).second = entry;
7✔
111
    }
7✔
112
  }
8✔
113
}
23✔
114

115
std::shared_ptr<TLSCtx> TCPOutConnectionManager::getTLSContext(const std::string& name, const ComboAddress& address, bool& verboseLogging, std::string& subjectName, std::string& subjectAddress, std::string& configName)
116
{
15✔
117
  TLSContextParameters tlsParams;
15✔
118
  tlsParams.d_provider = "openssl";
15✔
119
  tlsParams.d_validateCertificates = false;
15✔
120
  const pdns::rust::settings::rec::OutgoingTLSConfiguration* config{nullptr};
15✔
121

122
  {
15✔
123
    configName = "";
15✔
124
    auto table = s_outgoingTLSConfigTable.lock();
15✔
125
    if (auto* node = table->d_netmaskToConfig.lookup(address); node != nullptr) {
15✔
126
      config = &node->second;
7✔
127
    }
7✔
128
    else if (const auto* found = table->d_suffixToConfig.lookup(DNSName(name)); found != nullptr) {
8✔
129
      config = found;
3✔
130
    }
3✔
131
    if (config != nullptr) {
15✔
132
      configName = std::string(config->name);
10✔
133
      tlsParams.d_provider = std::string(config->provider);
10✔
134
      tlsParams.d_validateCertificates = config->validate_certificate;
10✔
135
      tlsParams.d_caStore = std::string(config->ca_store);
10✔
136
      if (!config->subject_name.empty()) {
10✔
137
        subjectName = std::string(config->subject_name);
5✔
138
      };
5✔
139
      if (!config->subject_address.empty()) {
10!
140
        subjectAddress = std::string(config->subject_address);
×
141
      };
×
142
      verboseLogging = config->verbose_logging;
10✔
143
      tlsParams.d_ciphers = std::string(config->ciphers);
10✔
144
      tlsParams.d_ciphers13 = std::string(config->ciphers_tls_13);
10✔
145
    }
10✔
146
  }
15✔
147
  return ::getTLSContext(tlsParams);
15✔
148
}
15✔
149

150
uint64_t getCurrentIdleTCPConnections()
151
{
183✔
152
  return broadcastAccFunction<uint64_t>([] { return t_tcp_manager.getSize(); });
948✔
153
}
183✔
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