30 uint8_t msg_type = holder->msg_type_;
32 <<
" (" <<
static_cast<int>(msg_type) <<
")"
33 <<
", trans_id=0x" << hex << holder->transid_ << dec;
34 if (!byhw && !holder->hwaddr_.empty()) {
36 }
else if (byhw && !holder->client_id_.empty()) {
46 :
thread_(this_thread::get_id()) {
51 if (!client_id && (!hwaddr || hwaddr->hwaddr_.empty())) {
52 isc_throw(InvalidParameter,
53 "null client-id and hwaddr in ClientHandler");
59 if (hwaddr && !hwaddr->hwaddr_.empty()) {
60 htype_ = hwaddr->htype_;
61 hwaddr_ = hwaddr->hwaddr_;
67mutex ClientHandler::mutex_;
69ClientHandler::ClientByIdContainer ClientHandler::clients_client_id_;
71ClientHandler::ClientByHWAddrContainer ClientHandler::clients_hwaddr_;
74ClientHandler::lookup(
const ClientIdPtr& client_id) {
80 auto it = clients_client_id_.find(client_id->getClientId());
81 if (it == clients_client_id_.end()) {
88ClientHandler::lookup(
const HWAddrPtr& hwaddr) {
93 if (hwaddr->hwaddr_.empty()) {
94 isc_throw(InvalidParameter,
"empty hwaddr in ClientHandler::lookup");
97 auto key = boost::make_tuple(hwaddr->htype_, hwaddr->hwaddr_);
98 auto it = clients_hwaddr_.find(key);
99 if (it == clients_hwaddr_.end()) {
106ClientHandler::addById(
const ClientPtr& client) {
109 isc_throw(InvalidParameter,
"null client in ClientHandler::addById");
113 clients_client_id_.insert(client);
117ClientHandler::addByHWAddr(
const ClientPtr& client) {
121 "null client in ClientHandler::addByHWAddr");
125 clients_hwaddr_.insert(client);
132 isc_throw(InvalidParameter,
"null client id in ClientHandler::del");
136 clients_client_id_.erase(client_id->getClientId());
140ClientHandler::del(
const HWAddrPtr& hwaddr) {
143 isc_throw(InvalidParameter,
"null hwaddr in ClientHandler::del");
145 if (hwaddr->hwaddr_.empty()) {
146 isc_throw(InvalidParameter,
"empty hwaddr in ClientHandler::del");
149 auto key = boost::make_tuple(hwaddr->htype_, hwaddr->hwaddr_);
151 auto it = clients_hwaddr_.find(key);
152 if (it == clients_hwaddr_.end()) {
156 clients_hwaddr_.erase(it);
160 : client_(), locked_client_id_(), locked_hwaddr_() {
164 bool unlocked =
false;
165 lock_guard<mutex> lk(mutex_);
166 if (locked_client_id_) {
170 if (locked_hwaddr_) {
174 if (!unlocked || !client_ || !client_->cont_) {
193 if (locked_client_id_) {
195 "already handling client-id in ClientHandler::tryLock");
197 if (locked_hwaddr_) {
199 "already handling hwaddr in ClientHandler::tryLock");
206 client_id.reset(
new ClientId(opt_client_id->getData()));
209 if (hwaddr && hwaddr->hwaddr_.empty()) {
212 if (!client_id && !hwaddr) {
216 client_.reset(
new Client(query, client_id, hwaddr));
223 lock_guard<mutex> lk(mutex_);
228 holder_id = lookup(client_id);
230 locked_client_id_ = client_id;
233 next_query_id = holder_id->next_query_;
234 holder_id->next_query_ = query;
235 holder_id->cont_ = cont;
244 holder_hw = lookup(hwaddr);
246 locked_hwaddr_ = hwaddr;
250 next_query_hw = holder_hw->next_query_;
251 holder_hw->next_query_ = query;
252 holder_hw->cont_ = cont;
265 .arg(
"client_id=" + client_id->toText())
266 .arg(next_query_id->toText())
267 .arg(this_thread::get_id())
268 .arg(summary(holder_id,
false))
269 .arg(holder_id->thread_);
271 static_cast<int64_t
>(1));
273 static_cast<int64_t
>(1));
280 .arg(
"client_id=" + client_id->toText())
281 .arg(query->toText())
282 .arg(this_thread::get_id())
283 .arg(summary(holder_id,
false))
284 .arg(holder_id->thread_);
286 static_cast<int64_t
>(1));
288 static_cast<int64_t
>(1));
292 auto makeHWAddrLabel = [hwaddr]() {
294 label <<
"hwtype=" <<
static_cast<int>(hwaddr->htype_)
296 return (label.str());
304 .arg(makeHWAddrLabel())
305 .arg(next_query_hw->toText())
306 .arg(this_thread::get_id())
307 .arg(summary(holder_hw,
true))
308 .arg(holder_hw->thread_);
310 static_cast<int64_t
>(1));
312 static_cast<int64_t
>(1));
319 .arg(makeHWAddrLabel())
320 .arg(query->toText())
321 .arg(this_thread::get_id())
322 .arg(summary(holder_hw,
true))
323 .arg(holder_hw->thread_);
325 static_cast<int64_t
>(1));
327 static_cast<int64_t
>(1));
334ClientHandler::lockById() {
336 if (!locked_client_id_) {
344ClientHandler::lockByHWAddr() {
346 if (!locked_hwaddr_) {
348 "nothing to lock in ClientHandler::lockByHWAddr");
351 addByHWAddr(client_);
355ClientHandler::unLockById() {
357 if (!locked_client_id_) {
359 "nothing to unlock in ClientHandler::unLockById");
362 del(locked_client_id_);
363 locked_client_id_.reset();
367ClientHandler::unLockByHWAddr() {
369 if (!locked_hwaddr_) {
371 "nothing to unlock in ClientHandler::unLockByHWAddr");
375 locked_hwaddr_.reset();
A generic exception that is thrown if a parameter given to a method or function is considered invalid...
A generic exception that is thrown when an unexpected error condition occurs.
virtual ~ClientHandler()
Destructor.
boost::shared_ptr< Client > ClientPtr
The type of shared pointers to clients.
bool tryLock(Pkt4Ptr query, ContinuationPtr cont=ContinuationPtr())
Tries to acquires a client.
ClientHandler()
Public interface.
Holds Client identifier or client IPv4 address.
const char * getName() const
Returns name of the DHCP message.
static StatsMgr & instance()
Statistics Manager accessor method.
static MultiThreadingMgr & instance()
Returns a single instance of Multi Threading Manager.
ThreadPool< std::function< void()> > & getThreadPool()
Get the dhcp thread pool.
bool getMode() const
Get the multi-threading mode.
Contains declarations for loggers used by the DHCPv4 server component.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
void addValue(const std::string &name, const int64_t value)
Records incremental integer observation.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
const isc::log::MessageID DHCP4_PACKET_DROP_0011
@ DHO_DHCP_CLIENT_IDENTIFIER
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
const isc::log::MessageID DHCP4_PACKET_QUEUE_FULL
isc::log::Logger bad_packet4_logger(DHCP4_BAD_PACKET_LOGGER_NAME)
Logger for rejected packets.
const int DBG_DHCP4_BASIC
Debug level used to trace basic operations within the code.
boost::shared_ptr< ClientId > ClientIdPtr
Shared pointer to a Client ID.
boost::shared_ptr< Continuation > ContinuationPtr
Define the type of shared pointers to continuations.
isc::log::Logger dhcp4_logger(DHCP4_APP_LOGGER_NAME)
Base logger for DHCPv4 server.
const isc::log::MessageID DHCP4_PACKET_DROP_0012
boost::shared_ptr< Option > OptionPtr
const int DBGLVL_PKT_HANDLING
This debug level is reserved for logging the details of packet handling, such as dropping the packet ...
string dumpAsHex(const uint8_t *data, size_t length)
Dumps a buffer of bytes as a string of hexadecimal digits.
Defines the logger used by the top-level component of kea-lfc.
Class (aka static) types, methods and members.
uint32_t transid_
Cached transaction ID.
std::vector< uint8_t > client_id_
Cached binary client ID.
Client(Pkt4Ptr query, ClientIdPtr client_id, HWAddrPtr hwaddr)
Constructor.
uint8_t msg_type_
Cached message type.
std::thread::id thread_
The ID of the thread processing the query.
bool addFront(const WorkItemPtr &item)
add a work item to the thread pool at front