24 : query_(query), htype_(
HTYPE_ETHER), thread_(this_thread::get_id()) {
29 if (!client_id && (!hwaddr || hwaddr->hwaddr_.empty())) {
31 "null client-id and hwaddr in ClientHandler");
35 duid_ = client_id->getDuid();
37 if (hwaddr && !hwaddr->hwaddr_.empty()) {
38 htype_ = hwaddr->htype_;
39 hwaddr_ = hwaddr->hwaddr_;
43 mutex ClientHandler::mutex_;
45 ClientHandler::ClientByIdContainer ClientHandler::clients_client_id_;
47 ClientHandler::ClientByHWAddrContainer ClientHandler::clients_hwaddr_;
49 ClientHandler::ClientPtr
50 ClientHandler::lookup(
const DuidPtr& duid) {
56 auto it = clients_client_id_.find(duid->getDuid());
57 if (it == clients_client_id_.end()) {
63 ClientHandler::ClientPtr
64 ClientHandler::lookup(
const HWAddrPtr& hwaddr) {
69 if (hwaddr->hwaddr_.empty()) {
73 auto key = boost::make_tuple(hwaddr->htype_, hwaddr->hwaddr_);
74 auto it = clients_hwaddr_.find(key);
75 if (it == clients_hwaddr_.end()) {
82 ClientHandler::addById(
const ClientPtr& client) {
89 clients_client_id_.insert(client);
93 ClientHandler::addByHWAddr(
const ClientPtr& client) {
97 "null client in ClientHandler::addByHWAddr");
101 clients_hwaddr_.insert(client);
105 ClientHandler::del(
const DuidPtr& duid) {
112 clients_client_id_.erase(duid->getDuid());
116 ClientHandler::del(
const HWAddrPtr& hwaddr) {
121 if (hwaddr->hwaddr_.empty()) {
125 auto key = boost::make_tuple(hwaddr->htype_, hwaddr->hwaddr_);
127 auto it = clients_hwaddr_.find(key);
128 if (it == clients_hwaddr_.end()) {
132 clients_hwaddr_.erase(it);
135 ClientHandler::ClientHandler()
136 : client_(), locked_client_id_(), locked_hwaddr_() {
140 bool unlocked =
false;
141 lock_guard<mutex> lk(mutex_);
142 if (locked_client_id_) {
146 if (locked_hwaddr_) {
150 if (!unlocked || !client_ || !client_->cont_) {
169 if (locked_client_id_) {
171 "already handling client-id in ClientHandler::tryLock");
173 if (locked_hwaddr_) {
175 "already handling hwaddr in ClientHandler::tryLock");
182 duid.reset(
new ClientId(opt_client_id->getData()));
185 if (hwaddr && hwaddr->hwaddr_.empty()) {
188 if (!duid && !hwaddr) {
197 client_.reset(
new Client(query, duid, hwaddr));
200 lock_guard<mutex> lk(mutex_);
205 holder_id = lookup(duid);
207 locked_client_id_ = duid;
210 next_query_id = holder_id->next_query_;
211 holder_id->next_query_ = query;
212 holder_id->cont_ = cont;
221 holder_hw = lookup(hwaddr);
223 locked_hwaddr_ = hwaddr;
227 next_query_hw = holder_hw->next_query_;
228 holder_hw->next_query_ = query;
229 holder_hw->cont_ = cont;
241 .arg(next_query_id->toText())
242 .arg(this_thread::get_id())
243 .arg(holder_id->query_->toText())
244 .arg(holder_id->thread_);
246 static_cast<int64_t
>(1));
252 .arg(query->toText())
253 .arg(this_thread::get_id())
254 .arg(holder_id->query_->toText())
255 .arg(holder_id->thread_);
257 static_cast<int64_t
>(1));
266 .arg(next_query_hw->toText())
267 .arg(this_thread::get_id())
268 .arg(holder_hw->query_->toText())
269 .arg(holder_hw->thread_);
271 static_cast<int64_t
>(1));
277 .arg(query->toText())
278 .arg(this_thread::get_id())
279 .arg(holder_hw->query_->toText())
280 .arg(holder_hw->thread_);
282 static_cast<int64_t
>(1));
289 ClientHandler::lockById() {
291 if (!locked_client_id_) {
299 ClientHandler::lockByHWAddr() {
301 if (!locked_hwaddr_) {
303 "nothing to lock in ClientHandler::lockByHWAddr");
306 addByHWAddr(client_);
310 ClientHandler::unLockById() {
312 if (!locked_client_id_) {
314 "nothing to unlock in ClientHandler::unLockById");
317 del(locked_client_id_);
318 locked_client_id_.reset();
322 ClientHandler::unLockByHWAddr() {
324 if (!locked_hwaddr_) {
326 "nothing to unlock in ClientHandler::unLockByHWAddr");
330 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.
bool tryLock(Pkt4Ptr query, ContinuationPtr cont=ContinuationPtr())
Tries to acquires a client.
Holds Client identifier or client IPv4 address.
static StatsMgr & instance()
Statistics Manager accessor method.
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< DUID > DuidPtr
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< 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
@ HTYPE_ETHER
Ethernet 10Mbps.
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 ...
Defines the logger used by the top-level component of kea-lfc.
bool addFront(const WorkItemPtr &item)
add a work item to the thread pool at front