23 : query_(query), htype_(
HTYPE_ETHER), thread_(this_thread::get_id()) {
28 if (!client_id && (!hwaddr || hwaddr->hwaddr_.empty())) {
30 "null client-id and hwaddr in ClientHandler");
34 duid_ = client_id->getDuid();
36 if (hwaddr && !hwaddr->hwaddr_.empty()) {
37 htype_ = hwaddr->htype_;
38 hwaddr_ = hwaddr->hwaddr_;
42 mutex ClientHandler::mutex_;
44 ClientHandler::ClientByIdContainer ClientHandler::clients_client_id_;
46 ClientHandler::ClientByHWAddrContainer ClientHandler::clients_hwaddr_;
48 ClientHandler::ClientPtr
49 ClientHandler::lookup(
const DuidPtr& duid) {
55 auto it = clients_client_id_.find(duid->getDuid());
56 if (it == clients_client_id_.end()) {
62 ClientHandler::ClientPtr
63 ClientHandler::lookup(
const HWAddrPtr& hwaddr) {
68 if (hwaddr->hwaddr_.empty()) {
72 auto key = boost::make_tuple(hwaddr->htype_, hwaddr->hwaddr_);
73 auto it = clients_hwaddr_.find(key);
74 if (it == clients_hwaddr_.end()) {
81 ClientHandler::addById(
const ClientPtr& client) {
88 clients_client_id_.insert(client);
92 ClientHandler::addByHWAddr(
const ClientPtr& client) {
96 "null client in ClientHandler::addByHWAddr");
100 clients_hwaddr_.insert(client);
104 ClientHandler::del(
const DuidPtr& duid) {
111 clients_client_id_.erase(duid->getDuid());
115 ClientHandler::del(
const HWAddrPtr& hwaddr) {
120 if (hwaddr->hwaddr_.empty()) {
124 auto key = boost::make_tuple(hwaddr->htype_, hwaddr->hwaddr_);
126 auto it = clients_hwaddr_.find(key);
127 if (it == clients_hwaddr_.end()) {
131 clients_hwaddr_.erase(it);
134 ClientHandler::ClientHandler()
135 : client_(), locked_client_id_(), locked_hwaddr_() {
139 bool unlocked =
false;
140 lock_guard<mutex> lk(mutex_);
141 if (locked_client_id_) {
145 if (locked_hwaddr_) {
149 if (!unlocked || !client_ || !client_->cont_) {
168 if (locked_client_id_) {
170 "already handling client-id in ClientHandler::tryLock");
172 if (locked_hwaddr_) {
174 "already handling hwaddr in ClientHandler::tryLock");
181 duid.reset(
new ClientId(opt_client_id->getData()));
184 if (hwaddr && hwaddr->hwaddr_.empty()) {
187 if (!duid && !hwaddr) {
196 client_.reset(
new Client(query, duid, hwaddr));
199 lock_guard<mutex> lk(mutex_);
204 holder_id = lookup(duid);
206 locked_client_id_ = duid;
209 next_query_id = holder_id->next_query_;
210 holder_id->next_query_ = query;
211 holder_id->cont_ = cont;
220 holder_hw = lookup(hwaddr);
222 locked_hwaddr_ = hwaddr;
226 next_query_hw = holder_hw->next_query_;
227 holder_hw->next_query_ = query;
228 holder_hw->cont_ = cont;
240 .arg(next_query_id->toText())
241 .arg(this_thread::get_id())
242 .arg(holder_id->query_->toText())
243 .arg(holder_id->thread_);
245 static_cast<int64_t>(1));
251 .arg(query->toText())
252 .arg(this_thread::get_id())
253 .arg(holder_id->query_->toText())
254 .arg(holder_id->thread_);
256 static_cast<int64_t>(1));
265 .arg(next_query_hw->toText())
266 .arg(this_thread::get_id())
267 .arg(holder_hw->query_->toText())
268 .arg(holder_hw->thread_);
270 static_cast<int64_t>(1));
276 .arg(query->toText())
277 .arg(this_thread::get_id())
278 .arg(holder_hw->query_->toText())
279 .arg(holder_hw->thread_);
281 static_cast<int64_t>(1));
288 ClientHandler::lockById() {
290 if (!locked_client_id_) {
298 ClientHandler::lockByHWAddr() {
300 if (!locked_hwaddr_) {
302 "nothing to lock in ClientHandler::lockByHWAddr");
305 addByHWAddr(client_);
309 ClientHandler::unLockById() {
311 if (!locked_client_id_) {
313 "nothing to unlock in ClientHandler::unLockById");
316 del(locked_client_id_);
317 locked_client_id_.reset();
321 ClientHandler::unLockByHWAddr() {
323 if (!locked_hwaddr_) {
325 "nothing to unlock in ClientHandler::unLockByHWAddr");
329 locked_hwaddr_.reset();
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
boost::shared_ptr< DUID > DuidPtr
A generic exception that is thrown if a parameter given to a method or function is considered invalid...
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
const isc::log::MessageID DHCP4_PACKET_QUEUE_FULL
boost::shared_ptr< Option > OptionPtr
isc::log::Logger bad_packet4_logger(DHCP4_BAD_PACKET_LOGGER_NAME)
Logger for rejected packets.
static StatsMgr & instance()
Statistics Manager accessor method.
const int DBG_DHCP4_BASIC
Debug level used to trace basic operations within the code.
bool addFront(const WorkItemPtr &item)
add a work item to the thread pool at front
isc::log::Logger dhcp4_logger(DHCP4_APP_LOGGER_NAME)
Base logger for DHCPv4 server.
const isc::log::MessageID DHCP4_PACKET_DROP_0012
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown when an unexpected error condition occurs.
bool getMode() const
Get the multi-threading mode.
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
virtual ~ClientHandler()
Destructor.
const isc::log::MessageID DHCP4_PACKET_DROP_0011
void addValue(const std::string &name, const int64_t value)
Records incremental integer observation.
Defines the logger used by the top-level component of kea-dhcp-ddns.
ThreadPool< std::function< void()> > & getThreadPool()
Get the dhcp thread pool.
Holds Client identifier or client IPv4 address.
bool tryLock(Pkt4Ptr query, ContinuationPtr cont=ContinuationPtr())
Tries to acquires a client.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
boost::shared_ptr< Continuation > ContinuationPtr
Define the type of shared pointers to continuations.
Contains declarations for loggers used by the DHCPv4 server component.