• 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

58.57
/pdns/fstrm_logger.cc
1
#include <unistd.h>
2
#include <sys/un.h>
3

4
#include "config.h"
5
#include "fstrm_logger.hh"
6

7
#ifdef RECURSOR
8
#include "logger.hh"
9
#include "logging.hh"
10
#else
11
#include "dolog.hh"
12
#endif
13

14
#ifdef HAVE_FSTRM
15

16
static const std::string DNSTAP_CONTENT_TYPE = "protobuf:dnstap.Dnstap";
17

18
FrameStreamLogger::FrameStreamLogger(const int family, std::string address, bool connect, const std::unordered_map<string, unsigned>& options) :
19
  d_family(family), d_address(std::move(address))
12✔
20
{
37✔
21
  try {
37✔
22
    d_fwopt = fstrm_writer_options_init();
37✔
23
    if (d_fwopt == nullptr) {
37!
24
      throw std::runtime_error("FrameStreamLogger: fstrm_writer_options_init failed.");
×
25
    }
×
26

27
    auto res = fstrm_writer_options_add_content_type(d_fwopt, DNSTAP_CONTENT_TYPE.c_str(), DNSTAP_CONTENT_TYPE.size());
37✔
28
    if (res != fstrm_res_success) {
37!
29
      throw std::runtime_error("FrameStreamLogger: fstrm_writer_options_add_content_type failed: " + std::to_string(res));
×
30
    }
×
31

32
    if (d_family == AF_UNIX) {
37✔
33
      struct sockaddr_un local{};
31✔
34
      if (makeUNsockaddr(d_address, &local) != 0) {
31!
35
        throw std::runtime_error("FrameStreamLogger: Unable to use '" + d_address + "', it is not a valid UNIX socket path.");
×
36
      }
×
37

38
      d_uwopt = fstrm_unix_writer_options_init();
31✔
39
      if (d_uwopt == nullptr) {
31!
40
        throw std::runtime_error("FrameStreamLogger: fstrm_unix_writer_options_init failed.");
×
41
      }
×
42

43
      // void return, no error checking.
44
      fstrm_unix_writer_options_set_socket_path(d_uwopt, d_address.c_str());
31✔
45

46
      d_writer = fstrm_unix_writer_init(d_uwopt, d_fwopt);
31✔
47
      if (d_writer == nullptr) {
31!
48
        throw std::runtime_error("FrameStreamLogger: fstrm_unix_writer_init() failed.");
×
49
      }
×
50
#ifdef HAVE_FSTRM_TCP_WRITER_INIT
31✔
51
    }
31✔
52
    else if (family == AF_INET || family == AF_INET6) {
6!
53
      d_twopt = fstrm_tcp_writer_options_init();
6✔
54
      if (d_twopt == nullptr) {
6!
55
        throw std::runtime_error("FrameStreamLogger: fstrm_tcp_writer_options_init failed.");
×
56
      }
×
57

58
      try {
6✔
59
        ComboAddress inetAddress(d_address);
6✔
60

61
        // void return, no error checking.
62
        fstrm_tcp_writer_options_set_socket_address(d_twopt, inetAddress.toString().c_str());
6✔
63
        fstrm_tcp_writer_options_set_socket_port(d_twopt, std::to_string(inetAddress.getPort()).c_str());
6✔
64
      }
6✔
65
      catch (PDNSException& e) {
6✔
66
        throw std::runtime_error("FrameStreamLogger: Unable to use '" + d_address + "': " + e.reason);
×
67
      }
×
68

69
      d_writer = fstrm_tcp_writer_init(d_twopt, d_fwopt);
6✔
70
      if (d_writer == nullptr) {
6!
71
        throw std::runtime_error("FrameStreamLogger: fstrm_tcp_writer_init() failed.");
×
72
      }
×
73
#endif
6✔
74
    }
6✔
75
    else {
×
76
      throw std::runtime_error("FrameStreamLogger: family " + std::to_string(family) + " not supported");
×
77
    }
×
78

79
    d_iothropt = fstrm_iothr_options_init();
37✔
80
    if (d_iothropt == nullptr) {
37!
81
      throw std::runtime_error("FrameStreamLogger: fstrm_iothr_options_init() failed.");
×
82
    }
×
83

84
    res = fstrm_iothr_options_set_queue_model(d_iothropt, FSTRM_IOTHR_QUEUE_MODEL_MPSC);
37✔
85
    if (res != fstrm_res_success) {
37!
86
      throw std::runtime_error("FrameStreamLogger: fstrm_iothr_options_set_queue_model failed: " + std::to_string(res));
×
87
    }
×
88

89
    struct setters
37✔
90
    {
37✔
91
      const std::string name;
37✔
92
      fstrm_res (*function)(struct fstrm_iothr_options*, const unsigned int);
37✔
93
    };
37✔
94
    const std::array<struct setters, 6> list = {{{"bufferHint", fstrm_iothr_options_set_buffer_hint},
37✔
95
                                                 {"flushTimeout", fstrm_iothr_options_set_flush_timeout},
37✔
96
                                                 {"inputQueueSize", fstrm_iothr_options_set_input_queue_size},
37✔
97
                                                 {"outputQueueSize", fstrm_iothr_options_set_output_queue_size},
37✔
98
                                                 {"queueNotifyThreshold", fstrm_iothr_options_set_queue_notify_threshold},
37✔
99
                                                 {"setReopenInterval", fstrm_iothr_options_set_reopen_interval}}};
37✔
100

101
    for (const auto& entry : list) {
221✔
102
      if (auto option = options.find(entry.name); option != options.end() && option->second != 0) {
221!
103
        auto result = entry.function(d_iothropt, option->second);
×
104
        if (result != fstrm_res_success) {
×
105
          throw std::runtime_error("FrameStreamLogger: setting " + string(entry.name) + " failed: " + std::to_string(result));
×
106
        }
×
107
      }
×
108
    }
221✔
109

110
    if (connect) {
37!
111
      d_iothr = fstrm_iothr_init(d_iothropt, &d_writer);
37✔
112
      if (d_iothr == nullptr) {
37!
113
        throw std::runtime_error("FrameStreamLogger: fstrm_iothr_init() failed.");
×
114
      }
×
115

116
      d_ioqueue = fstrm_iothr_get_input_queue(d_iothr);
37✔
117
      if (d_ioqueue == nullptr) {
37!
118
        throw std::runtime_error("FrameStreamLogger: fstrm_iothr_get_input_queue() failed.");
×
119
      }
×
120
    }
37✔
121
  }
37✔
122
  catch (std::runtime_error& e) {
37✔
123
    this->cleanup();
×
124
    throw;
×
125
  }
×
126
}
37✔
127

128
void FrameStreamLogger::cleanup()
129
{
25✔
130
  if (d_iothr != nullptr) {
25!
131
    fstrm_iothr_destroy(&d_iothr);
25✔
132
    d_iothr = nullptr;
25✔
133
  }
25✔
134
  if (d_iothropt != nullptr) {
25!
135
    fstrm_iothr_options_destroy(&d_iothropt);
25✔
136
    d_iothropt = nullptr;
25✔
137
  }
25✔
138
  if (d_writer != nullptr) {
25!
139
    fstrm_writer_destroy(&d_writer);
×
140
    d_writer = nullptr;
×
141
  }
×
142
  if (d_uwopt != nullptr) {
25!
143
    fstrm_unix_writer_options_destroy(&d_uwopt);
25✔
144
    d_uwopt = nullptr;
25✔
145
  }
25✔
146
#ifdef HAVE_FSTRM_TCP_WRITER_INIT
25✔
147
  if (d_twopt != nullptr) {
25!
148
    fstrm_tcp_writer_options_destroy(&d_twopt);
×
149
    d_twopt = nullptr;
×
150
  }
×
151
#endif
25✔
152
  if (d_fwopt != nullptr) {
25!
153
    fstrm_writer_options_destroy(&d_fwopt);
25✔
154
    d_fwopt = nullptr;
25✔
155
  }
25✔
156
}
25✔
157

158
FrameStreamLogger::~FrameStreamLogger()
159
{
25✔
160
  this->cleanup();
25✔
161
}
25✔
162

163
RemoteLoggerInterface::Result FrameStreamLogger::queueData(const std::string& data)
164
{
20✔
165
  if ((d_ioqueue == nullptr) || d_iothr == nullptr) {
20!
166
    ++d_permanentFailures;
×
167
    return Result::OtherError;
×
168
  }
×
169
  uint8_t* frame = (uint8_t*)malloc(data.length()); // NOLINT: it's the API
20✔
170
  if (frame == nullptr) {
20!
171
    ++d_tooLargeCount;
×
172
    return Result::TooLarge;
×
173
  }
×
174
  memcpy(frame, data.c_str(), data.length());
20✔
175

176
  auto res = fstrm_iothr_submit(d_iothr, d_ioqueue, frame, data.length(), fstrm_free_wrapper, nullptr);
20✔
177

178
  if (res == fstrm_res_success) {
20!
179
    // Frame successfully queued.
180
    ++d_framesSent;
20✔
181
    // do not call free here
182
    return Result::Queued;
20✔
183
  }
20✔
184
  if (res == fstrm_res_again) {
×
185
    free(frame); // NOLINT: it's the API
×
186
    ++d_queueFullDrops;
×
187
    return Result::PipeFull;
×
188
  }
×
189
  // Permanent failure.
190
  free(frame); // NOLINT: it's the API
×
191
  ++d_permanentFailures;
×
192
  return Result::OtherError;
×
193
}
×
194

195
#endif /* HAVE_FSTRM */
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