Kea  2.3.9
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
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:246
DHCPv4 packet queue buffer implementation.
PacketQueueRing4(const std::string &queue_type, size_t capacity)
Constructor.
virtual ~PacketQueueRing4()
virtual Destructor
DHCPv6 packet queue buffer implementation.
PacketQueueRing6(const std::string &queue_type, size_t capacity)
Constructor.
virtual ~PacketQueueRing6()
virtual Destructor
Provides a ring-buffer implementation of the PacketQueue interface.
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.
Interface for managing a queue of inbound DHCP packets.
Definition: packet_queue.h:47
virtual data::ElementPtr getInfo() const
Fetches operational information about the current state of the queue.
Definition: packet_queue.h:99
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< Element > ElementPtr
Definition: data.h:26
@ info
Definition: db_log.h:118
QueueEnd
Enumerates choices between the two ends of the queue.
Definition: packet_queue.h:31
Defines the logger used by the top-level component of kea-lfc.
Holds information about socket.
Definition: socket_info.h:19