Kea 2.6.2
packet_queue_ring.h
Go to the documentation of this file.
1// Copyright (C) 2018-2022 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#ifndef PACKET_QUEUE_RING_H
8#define PACKET_QUEUE_RING_H
9
10#include <dhcp/packet_queue.h>
11
12#include <boost/circular_buffer.hpp>
13#include <boost/scoped_ptr.hpp>
14#include <sstream>
15#include <mutex>
16
17namespace isc {
18
19namespace dhcp {
20
25template<typename PacketTypePtr>
26class PacketQueueRing : public PacketQueue<PacketTypePtr> {
27public:
30 static const size_t MIN_RING_CAPACITY = 5;
31
36 PacketQueueRing(const std::string& queue_type, size_t capacity)
37 : PacketQueue<PacketTypePtr>(queue_type) {
38 queue_.set_capacity(capacity);
39 mutex_.reset(new std::mutex);
40 }
41
43 virtual ~PacketQueueRing(){};
44
53 virtual void enqueuePacket(PacketTypePtr packet, const SocketInfo& source) {
54 if (!shouldDropPacket(packet, source)) {
56 }
57 }
58
65 virtual PacketTypePtr dequeuePacket() {
67 return (popPacket());
68 }
69
82 virtual bool shouldDropPacket(PacketTypePtr /* packet */,
83 const SocketInfo& /* source */) {
84 return (false);
85 }
86
97 virtual int eatPackets(const QueueEnd& /* from */) {
98 return (0);
99 }
100
108 virtual void pushPacket(PacketTypePtr& packet, const QueueEnd& to=QueueEnd::BACK) {
109 std::lock_guard<std::mutex> lock(*mutex_);
110 if (to == QueueEnd::BACK) {
111 queue_.push_back(packet);
112 } else {
113 queue_.push_front(packet);
114 }
115 }
116
126 virtual PacketTypePtr popPacket(const QueueEnd& from = QueueEnd::FRONT) {
127 PacketTypePtr packet;
128 std::lock_guard<std::mutex> lock(*mutex_);
129
130 if (queue_.empty()) {
131 return (packet);
132 }
133
134 if (from == QueueEnd::FRONT) {
135 packet = queue_.front();
136 queue_.pop_front();
137 } else {
138 packet = queue_.back();
139 queue_.pop_back();
140 }
141
142 return (packet);
143 }
144
145
155 virtual const PacketTypePtr peek(const QueueEnd& from=QueueEnd::FRONT) const {
156 PacketTypePtr packet;
157 if (!queue_.empty()) {
158 packet = (from == QueueEnd::FRONT ? queue_.front() : queue_.back());
159 }
160
161 return (packet);
162 }
163
165 virtual bool empty() const {
166 std::lock_guard<std::mutex> lock(*mutex_);
167 return (queue_.empty());
168 }
169
171 virtual size_t getCapacity() const {
172 return (queue_.capacity());
173 }
174
181 virtual void setCapacity(size_t capacity) {
182 if (capacity < MIN_RING_CAPACITY) {
183 isc_throw(BadValue, "Queue capacity of " << capacity
184 << " is invalid. It must be at least "
186 }
187
189 queue_.set_capacity(capacity);
190 }
191
193 virtual size_t getSize() const {
194 return (queue_.size());
195 }
196
198 virtual void clear() {
199 queue_.clear();
200 }
201
203 virtual data::ElementPtr getInfo() const {
205 info->set("capacity", data::Element::create(static_cast<int64_t>(getCapacity())));
206 info->set("size", data::Element::create(static_cast<int64_t>(getSize())));
207 return (info);
208 }
209
210private:
211
213 boost::circular_buffer<PacketTypePtr> queue_;
214
216 boost::scoped_ptr<std::mutex> mutex_;
217};
218
219
226class PacketQueueRing4 : public PacketQueueRing<Pkt4Ptr> {
227public:
232 PacketQueueRing4(const std::string& queue_type, size_t capacity)
233 : PacketQueueRing(queue_type, capacity) {
234 };
235
238};
239
246class PacketQueueRing6 : public PacketQueueRing<Pkt6Ptr> {
247public:
252 PacketQueueRing6(const std::string& queue_type, size_t capacity)
253 : PacketQueueRing(queue_type, capacity) {
254 };
255
258};
259
260}; // namespace isc::dhcp
261}; // namespace isc
262
263#endif // PACKET_QUEUE_RING_H
read_packet FORK if not parent: break YIELD answer=DNSLookup(packet, this) response=DNSAnswer(answer) YIELD send(response) At each "YIELD" point, the coroutine initiates an asynchronous operation, then pauses and turns over control to some other task on the ASIO service queue. When the operation completes, the coroutine resumes. The DNSLookup and DNSAnswer define callback methods used by a DNS Server to communicate with the module that called it. They are abstract-only classes whose concrete implementations are supplied by the calling module. The DNSLookup callback always runs asynchronously. Concrete implementations must be sure to call the server 's "resume" method when it is finished. In an authoritative server, the DNSLookup implementation would examine the query, look up the answer, then call "resume"(See the diagram in doc/auth_process.jpg). In a recursive server, the DNSLookup implementation would initiate a DNSQuery, which in turn would be responsible for calling the server 's "resume" method(See the diagram in doc/recursive_process.jpg). A DNSQuery object is intended to handle resolution of a query over the network when the local authoritative data sources or cache are not sufficient. The plan is that it will make use of subsidiary DNSFetch calls to get data from particular authoritative servers, and when it has gotten a complete answer, it calls "resume". In current form, however, DNSQuery is much simpler packet
Definition asiodns.dox:24
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
static ElementPtr create(const Position &pos=ZERO_POSITION())
Definition data.cc:249
PacketQueueRing4(const std::string &queue_type, size_t capacity)
Constructor.
virtual ~PacketQueueRing4()
virtual Destructor
PacketQueueRing6(const std::string &queue_type, size_t capacity)
Constructor.
virtual ~PacketQueueRing6()
virtual Destructor
virtual void pushPacket(PacketTypePtr &packet, const QueueEnd &to=QueueEnd::BACK)
Pushes a packet onto the queue.
virtual void enqueuePacket(PacketTypePtr packet, const SocketInfo &source)
Adds a packet to the queue.
virtual size_t getSize() const
Returns the current number of packets in the buffer.
virtual void setCapacity(size_t capacity)
Sets the maximum number of packets allowed in the buffer.
virtual data::ElementPtr getInfo() const
Fetches pertinent information.
virtual size_t getCapacity() const
Returns the maximum number of packets allowed in the buffer.
virtual int eatPackets(const QueueEnd &)
Discards packets from one end of the queue.
virtual bool empty() const
Returns True if the queue is empty.
virtual bool shouldDropPacket(PacketTypePtr, const SocketInfo &)
Determines if a packet should be discarded.
virtual const PacketTypePtr peek(const QueueEnd &from=QueueEnd::FRONT) const
Gets the packet currently at one end of the queue.
virtual ~PacketQueueRing()
virtual Destructor
virtual PacketTypePtr dequeuePacket()
Dequeues the next packet from the queue.
virtual PacketTypePtr popPacket(const QueueEnd &from=QueueEnd::FRONT)
Pops a packet from the queue.
virtual void clear()
Discards all packets currently in the buffer.
PacketQueueRing(const std::string &queue_type, size_t capacity)
Constructor.
static const size_t MIN_RING_CAPACITY
Minimum queue capacity permitted.
virtual data::ElementPtr getInfo() const
Fetches operational information about the current state of the queue.
PacketQueue(const std::string &queue_type)
Constructor.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< Element > ElementPtr
Definition data.h:28
@ info
Definition db_log.h:120
QueueEnd
Enumerates choices between the two ends of the queue.
Defines the logger used by the top-level component of kea-lfc.
Holds information about socket.
Definition socket_info.h:19