Kea  2.3.2-git
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 
17 namespace isc {
18 
19 namespace dhcp {
20 
25 template<typename PacketTypePtr>
26 class PacketQueueRing : public PacketQueue<PacketTypePtr> {
27 public:
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)) {
55  pushPacket(packet);
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 "
185  << MIN_RING_CAPACITY);
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 
210 private:
211 
213  boost::circular_buffer<PacketTypePtr> queue_;
214 
216  boost::scoped_ptr<std::mutex> mutex_;
217 };
218 
219 
226 class PacketQueueRing4 : public PacketQueueRing<Pkt4Ptr> {
227 public:
232  PacketQueueRing4(const std::string& queue_type, size_t capacity)
233  : PacketQueueRing(queue_type, capacity) {
234  };
235 
237  virtual ~PacketQueueRing4(){}
238 };
239 
246 class PacketQueueRing6 : public PacketQueueRing<Pkt6Ptr> {
247 public:
252  PacketQueueRing6(const std::string& queue_type, size_t capacity)
253  : PacketQueueRing(queue_type, capacity) {
254  };
255 
257  virtual ~PacketQueueRing6(){}
258 };
259 
260 }; // namespace isc::dhcp
261 }; // namespace isc
262 
263 #endif // PACKET_QUEUE_RING_H
virtual const PacketTypePtr peek(const QueueEnd &from=QueueEnd::FRONT) const
Gets the packet currently at one end of the queue.
virtual data::ElementPtr getInfo() const
Fetches operational information about the current state of the queue.
Definition: packet_queue.h:99
Interface for managing a queue of inbound DHCP packets.
Definition: packet_queue.h:47
boost::shared_ptr< Element > ElementPtr
Definition: data.h:24
virtual void setCapacity(size_t capacity)
Sets the maximum number of packets allowed in the buffer.
virtual size_t getCapacity() const
Returns the maximum number of packets allowed in the buffer.
QueueEnd
Enumerates choices between the two ends of the queue.
Definition: packet_queue.h:31
Provides a ring-buffer implementation of the PacketQueue interface.
virtual PacketTypePtr popPacket(const QueueEnd &from=QueueEnd::FRONT)
Pops a packet from the queue.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
virtual bool shouldDropPacket(PacketTypePtr, const SocketInfo &)
Determines if a packet should be discarded.
virtual int eatPackets(const QueueEnd &)
Discards packets from one end of the queue.
DHCPv4 packet queue buffer implementation.
virtual void clear()
Discards all packets currently in the buffer.
virtual PacketTypePtr dequeuePacket()
Dequeues the next packet from the queue.
Defines the logger used by the top-level component of kea-lfc.
virtual data::ElementPtr getInfo() const
Fetches pertinent information.
virtual void pushPacket(PacketTypePtr &packet, const QueueEnd &to=QueueEnd::BACK)
Pushes a packet onto the queue.
static ElementPtr create(const Position &pos=ZERO_POSITION())
Definition: data.cc:241
PacketQueueRing(const std::string &queue_type, size_t capacity)
Constructor.
PacketQueueRing6(const std::string &queue_type, size_t capacity)
Constructor.
virtual void enqueuePacket(PacketTypePtr packet, const SocketInfo &source)
Adds a packet to the queue.
virtual ~PacketQueueRing()
virtual Destructor
static const size_t MIN_RING_CAPACITY
Minimum queue capacity permitted.
DHCPv6 packet queue buffer implementation.
virtual ~PacketQueueRing4()
virtual Destructor
virtual ~PacketQueueRing6()
virtual Destructor
Holds information about socket.
Definition: socket_info.h:19
virtual size_t getSize() const
Returns the current number of packets in the buffer.
virtual bool empty() const
Returns True if the queue is empty.
PacketQueueRing4(const std::string &queue_type, size_t capacity)
Constructor.