1 //
2 // Copyright (C) 2012 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include "shill/net/netlink_manager.h"
18
19 #include <errno.h>
20 #include <sys/select.h>
21 #include <sys/time.h>
22
23 #include <list>
24 #include <map>
25 #include <queue>
26
27 #include <base/location.h>
28 #include <base/logging.h>
29 #include <base/memory/weak_ptr.h>
30 #include <base/message_loop/message_loop.h>
31 #include <base/stl_util.h>
32
33 #include "shill/net/attribute_list.h"
34 #include "shill/net/generic_netlink_message.h"
35 #include "shill/net/io_handler.h"
36 #include "shill/net/netlink_message.h"
37 #include "shill/net/netlink_packet.h"
38 #include "shill/net/nl80211_message.h"
39 #include "shill/net/shill_time.h"
40 #include "shill/net/sockets.h"
41
42 using base::Bind;
43 using base::LazyInstance;
44 using base::MessageLoop;
45 using std::list;
46 using std::map;
47 using std::string;
48
49 namespace shill {
50
51 namespace {
52 LazyInstance<NetlinkManager> g_netlink_manager = LAZY_INSTANCE_INITIALIZER;
53 } // namespace
54
55 const char NetlinkManager::kEventTypeConfig[] = "config";
56 const char NetlinkManager::kEventTypeScan[] = "scan";
57 const char NetlinkManager::kEventTypeRegulatory[] = "regulatory";
58 const char NetlinkManager::kEventTypeMlme[] = "mlme";
59 const long NetlinkManager::kMaximumNewFamilyWaitSeconds = 1; // NOLINT
60 const long NetlinkManager::kMaximumNewFamilyWaitMicroSeconds = 0; // NOLINT
61 const long NetlinkManager::kResponseTimeoutSeconds = 5; // NOLINT
62 const long NetlinkManager::kResponseTimeoutMicroSeconds = 0; // NOLINT
63 const long NetlinkManager::kPendingDumpTimeoutMilliseconds = 500; // NOLINT
64 const long NetlinkManager::kNlMessageRetryDelayMilliseconds = 300; // NOLINT
65 const int NetlinkManager::kMaxNlMessageRetries = 1; // NOLINT
66
NetlinkResponseHandler(const NetlinkManager::NetlinkAckHandler & ack_handler,const NetlinkManager::NetlinkAuxilliaryMessageHandler & error_handler)67 NetlinkManager::NetlinkResponseHandler::NetlinkResponseHandler(
68 const NetlinkManager::NetlinkAckHandler& ack_handler,
69 const NetlinkManager::NetlinkAuxilliaryMessageHandler& error_handler)
70 : ack_handler_(ack_handler),
71 error_handler_(error_handler) {}
72
~NetlinkResponseHandler()73 NetlinkManager::NetlinkResponseHandler::~NetlinkResponseHandler() {}
74
HandleError(AuxilliaryMessageType type,const NetlinkMessage * netlink_message) const75 void NetlinkManager::NetlinkResponseHandler::HandleError(
76 AuxilliaryMessageType type, const NetlinkMessage* netlink_message) const {
77 if (!error_handler_.is_null())
78 error_handler_.Run(type, netlink_message);
79 }
80
HandleAck() const81 bool NetlinkManager::NetlinkResponseHandler::HandleAck() const {
82 if (!ack_handler_.is_null()) {
83 // Default behavior is not to remove callbacks. In the case where the
84 // callback is not successfully invoked, this is safe as it does not
85 // prevent any further responses from behind handled.
86 bool remove_callbacks = false;
87 ack_handler_.Run(&remove_callbacks);
88 // If there are no other handlers other than the Ack handler, then force
89 // the callback to be removed after handling the Ack.
90 return remove_callbacks || error_handler_.is_null();
91 } else {
92 // If there is no Ack handler, do not delete registered callbacks
93 // for this function because we are not explicitly told to do so.
94 return false;
95 }
96 }
97
98 class ControlResponseHandler : public NetlinkManager::NetlinkResponseHandler {
99 public:
ControlResponseHandler(const NetlinkManager::NetlinkAckHandler & ack_handler,const NetlinkManager::NetlinkAuxilliaryMessageHandler & error_handler,const NetlinkManager::ControlNetlinkMessageHandler & handler)100 ControlResponseHandler(
101 const NetlinkManager::NetlinkAckHandler& ack_handler,
102 const NetlinkManager::NetlinkAuxilliaryMessageHandler& error_handler,
103 const NetlinkManager::ControlNetlinkMessageHandler& handler)
104 : NetlinkManager::NetlinkResponseHandler(ack_handler, error_handler),
105 handler_(handler) {}
106
HandleMessage(const NetlinkMessage & netlink_message) const107 bool HandleMessage(const NetlinkMessage& netlink_message) const override {
108 if (netlink_message.message_type() !=
109 ControlNetlinkMessage::GetMessageType()) {
110 LOG(ERROR) << "Message is type " << netlink_message.message_type()
111 << ", not " << ControlNetlinkMessage::GetMessageType()
112 << " (Control).";
113 return false;
114 }
115 if (!handler_.is_null()) {
116 const ControlNetlinkMessage* message =
117 static_cast<const ControlNetlinkMessage*>(&netlink_message);
118 handler_.Run(*message);
119 }
120 return true;
121 }
122
HandleAck() const123 bool HandleAck() const override {
124 if (handler_.is_null()) {
125 return NetlinkManager::NetlinkResponseHandler::HandleAck();
126 } else {
127 bool remove_callbacks = false;
128 NetlinkManager::NetlinkResponseHandler::ack_handler_.Run(
129 &remove_callbacks);
130 return remove_callbacks;
131 }
132 }
133
134 private:
135 NetlinkManager::ControlNetlinkMessageHandler handler_;
136
137 DISALLOW_COPY_AND_ASSIGN(ControlResponseHandler);
138 };
139
140 class Nl80211ResponseHandler : public NetlinkManager::NetlinkResponseHandler {
141 public:
Nl80211ResponseHandler(const NetlinkManager::NetlinkAckHandler & ack_handler,const NetlinkManager::NetlinkAuxilliaryMessageHandler & error_handler,const NetlinkManager::Nl80211MessageHandler & handler)142 Nl80211ResponseHandler(
143 const NetlinkManager::NetlinkAckHandler& ack_handler,
144 const NetlinkManager::NetlinkAuxilliaryMessageHandler& error_handler,
145 const NetlinkManager::Nl80211MessageHandler& handler)
146 : NetlinkManager::NetlinkResponseHandler(ack_handler, error_handler),
147 handler_(handler) {}
148
HandleMessage(const NetlinkMessage & netlink_message) const149 bool HandleMessage(const NetlinkMessage& netlink_message) const override {
150 if (netlink_message.message_type() != Nl80211Message::GetMessageType()) {
151 LOG(ERROR) << "Message is type " << netlink_message.message_type()
152 << ", not " << Nl80211Message::GetMessageType()
153 << " (Nl80211).";
154 return false;
155 }
156 if (!handler_.is_null()) {
157 const Nl80211Message* message =
158 static_cast<const Nl80211Message*>(&netlink_message);
159 handler_.Run(*message);
160 }
161 return true;
162 }
163
HandleAck() const164 bool HandleAck() const override {
165 if (handler_.is_null()) {
166 return NetlinkManager::NetlinkResponseHandler::HandleAck();
167 } else {
168 bool remove_callbacks = false;
169 NetlinkManager::NetlinkResponseHandler::ack_handler_.Run(
170 &remove_callbacks);
171 return remove_callbacks;
172 }
173 }
174
175 private:
176 NetlinkManager::Nl80211MessageHandler handler_;
177
178 DISALLOW_COPY_AND_ASSIGN(Nl80211ResponseHandler);
179 };
180
181
MessageType()182 NetlinkManager::MessageType::MessageType() :
183 family_id(NetlinkMessage::kIllegalMessageType) {}
184
NetlinkManager()185 NetlinkManager::NetlinkManager()
186 : weak_ptr_factory_(this),
187 dispatcher_callback_(Bind(&NetlinkManager::OnRawNlMessageReceived,
188 weak_ptr_factory_.GetWeakPtr())),
189 time_(Time::GetInstance()),
190 io_handler_factory_(
191 IOHandlerFactoryContainer::GetInstance()->GetIOHandlerFactory()),
192 dump_pending_(false) {}
193
~NetlinkManager()194 NetlinkManager::~NetlinkManager() {}
195
GetInstance()196 NetlinkManager* NetlinkManager::GetInstance() {
197 return g_netlink_manager.Pointer();
198 }
199
Reset(bool full)200 void NetlinkManager::Reset(bool full) {
201 ClearBroadcastHandlers();
202 message_handlers_.clear();
203 message_types_.clear();
204 while (!pending_messages_.empty()) {
205 pending_messages_.pop();
206 }
207 pending_dump_timeout_callback_.Cancel();
208 resend_dump_message_callback_.Cancel();
209 dump_pending_ = false;
210 if (full) {
211 sock_.reset();
212 }
213 }
214
OnNewFamilyMessage(const ControlNetlinkMessage & message)215 void NetlinkManager::OnNewFamilyMessage(const ControlNetlinkMessage& message) {
216 uint16_t family_id;
217 string family_name;
218
219 if (!message.const_attributes()->GetU16AttributeValue(CTRL_ATTR_FAMILY_ID,
220 &family_id)) {
221 LOG(ERROR) << __func__ << ": Couldn't get family_id attribute";
222 return;
223 }
224
225 if (!message.const_attributes()->GetStringAttributeValue(
226 CTRL_ATTR_FAMILY_NAME, &family_name)) {
227 LOG(ERROR) << __func__ << ": Couldn't get family_name attribute";
228 return;
229 }
230
231 VLOG(3) << "Socket family '" << family_name << "' has id=" << family_id;
232
233 // Extract the available multicast groups from the message.
234 AttributeListConstRefPtr multicast_groups;
235 if (message.const_attributes()->ConstGetNestedAttributeList(
236 CTRL_ATTR_MCAST_GROUPS, &multicast_groups)) {
237 AttributeListConstRefPtr current_group;
238
239 for (int i = 1;
240 multicast_groups->ConstGetNestedAttributeList(i, ¤t_group);
241 ++i) {
242 string group_name;
243 uint32_t group_id;
244 if (!current_group->GetStringAttributeValue(CTRL_ATTR_MCAST_GRP_NAME,
245 &group_name)) {
246 LOG(WARNING) << "Expected CTRL_ATTR_MCAST_GRP_NAME, found none";
247 continue;
248 }
249 if (!current_group->GetU32AttributeValue(CTRL_ATTR_MCAST_GRP_ID,
250 &group_id)) {
251 LOG(WARNING) << "Expected CTRL_ATTR_MCAST_GRP_ID, found none";
252 continue;
253 }
254 VLOG(3) << " Adding group '" << group_name << "' = " << group_id;
255 message_types_[family_name].groups[group_name] = group_id;
256 }
257 }
258
259 message_types_[family_name].family_id = family_id;
260 }
261
262 // static
OnNetlinkMessageError(AuxilliaryMessageType type,const NetlinkMessage * raw_message)263 void NetlinkManager::OnNetlinkMessageError(AuxilliaryMessageType type,
264 const NetlinkMessage* raw_message) {
265 switch (type) {
266 case kErrorFromKernel:
267 if (!raw_message) {
268 LOG(ERROR) << "Unknown error from kernel.";
269 break;
270 }
271 if (raw_message->message_type() == ErrorAckMessage::GetMessageType()) {
272 const ErrorAckMessage* error_ack_message =
273 static_cast<const ErrorAckMessage*>(raw_message);
274 // error_ack_message->error() should be non-zero (i.e. not an ACK),
275 // since ACKs would be routed to a NetlinkAckHandler in
276 // NetlinkManager::OnNlMessageReceived.
277 LOG(ERROR) << __func__
278 << ": Message (seq: " << error_ack_message->sequence_number()
279 << ") failed: " << error_ack_message->ToString();
280 }
281 break;
282
283 case kUnexpectedResponseType:
284 LOG(ERROR) << "Message not handled by regular message handler:";
285 if (raw_message) {
286 raw_message->Print(0, 0);
287 }
288 break;
289
290 case kTimeoutWaitingForResponse:
291 LOG(WARNING) << "Timeout waiting for response";
292 break;
293
294 default:
295 LOG(ERROR) << "Unexpected auxilliary message type: " << type;
296 break;
297 }
298 }
299
Init()300 bool NetlinkManager::Init() {
301 // Install message factory for control class of messages, which has
302 // statically-known message type.
303 message_factory_.AddFactoryMethod(
304 ControlNetlinkMessage::kMessageType,
305 Bind(&ControlNetlinkMessage::CreateMessage));
306 if (!sock_) {
307 sock_.reset(new NetlinkSocket);
308 if (!sock_) {
309 LOG(ERROR) << "No memory";
310 return false;
311 }
312
313 if (!sock_->Init()) {
314 return false;
315 }
316 }
317 return true;
318 }
319
Start()320 void NetlinkManager::Start() {
321 // Create an IO handler for receiving messages on the netlink socket.
322 // IO handler will be installed to the current message loop.
323 dispatcher_handler_.reset(io_handler_factory_->CreateIOInputHandler(
324 file_descriptor(),
325 dispatcher_callback_,
326 Bind(&NetlinkManager::OnReadError, weak_ptr_factory_.GetWeakPtr())));
327 }
328
file_descriptor() const329 int NetlinkManager::file_descriptor() const {
330 return (sock_ ? sock_->file_descriptor() : Sockets::kInvalidFileDescriptor);
331 }
332
GetFamily(const string & name,const NetlinkMessageFactory::FactoryMethod & message_factory)333 uint16_t NetlinkManager::GetFamily(const string& name,
334 const NetlinkMessageFactory::FactoryMethod& message_factory) {
335 MessageType& message_type = message_types_[name];
336 if (message_type.family_id != NetlinkMessage::kIllegalMessageType) {
337 return message_type.family_id;
338 }
339 if (!sock_) {
340 LOG(FATAL) << "Must call |Init| before this method.";
341 return false;
342 }
343
344 GetFamilyMessage msg;
345 if (!msg.attributes()->SetStringAttributeValue(CTRL_ATTR_FAMILY_NAME, name)) {
346 LOG(ERROR) << "Couldn't set string attribute";
347 return false;
348 }
349 SendControlMessage(&msg,
350 Bind(&NetlinkManager::OnNewFamilyMessage,
351 weak_ptr_factory_.GetWeakPtr()),
352 Bind(&NetlinkManager::OnAckDoNothing),
353 Bind(&NetlinkManager::OnNetlinkMessageError));
354
355 // Wait for a response. The code absolutely needs family_ids for its
356 // message types so we do a synchronous wait. It's OK to do this because
357 // a) libnl does a synchronous wait (so there's prior art), b) waiting
358 // asynchronously would add significant and unnecessary complexity to the
359 // code that deals with pending messages that could, potentially, be waiting
360 // for a message type, and c) it really doesn't take very long for the
361 // GETFAMILY / NEWFAMILY transaction to transpire (this transaction was timed
362 // over 20 times and found a maximum duration of 11.1 microseconds and an
363 // average of 4.0 microseconds).
364 struct timeval now, end_time;
365 struct timeval maximum_wait_duration = {kMaximumNewFamilyWaitSeconds,
366 kMaximumNewFamilyWaitMicroSeconds};
367 time_->GetTimeMonotonic(&now);
368 timeradd(&now, &maximum_wait_duration, &end_time);
369
370 do {
371 // Wait with timeout for a message from the netlink socket.
372 fd_set read_fds;
373 FD_ZERO(&read_fds);
374
375 int socket = file_descriptor();
376 if (socket >= FD_SETSIZE)
377 LOG(FATAL) << "Invalid file_descriptor.";
378 FD_SET(socket, &read_fds);
379
380 struct timeval wait_duration;
381 timersub(&end_time, &now, &wait_duration);
382 int result = sock_->sockets()->Select(file_descriptor() + 1,
383 &read_fds,
384 nullptr,
385 nullptr,
386 &wait_duration);
387 if (result < 0) {
388 PLOG(ERROR) << "Select failed";
389 return NetlinkMessage::kIllegalMessageType;
390 }
391 if (result == 0) {
392 LOG(WARNING) << "Timed out waiting for family_id for family '"
393 << name << "'.";
394 return NetlinkMessage::kIllegalMessageType;
395 }
396
397 // Read and process any messages.
398 ByteString received;
399 sock_->RecvMessage(&received);
400 InputData input_data(received.GetData(), received.GetLength());
401 OnRawNlMessageReceived(&input_data);
402 if (message_type.family_id != NetlinkMessage::kIllegalMessageType) {
403 uint16_t family_id = message_type.family_id;
404 if (family_id != NetlinkMessage::kIllegalMessageType) {
405 message_factory_.AddFactoryMethod(family_id, message_factory);
406 }
407 return message_type.family_id;
408 }
409 time_->GetTimeMonotonic(&now);
410 } while (timercmp(&now, &end_time, <));
411
412 LOG(ERROR) << "Timed out waiting for family_id for family '" << name << "'.";
413 return NetlinkMessage::kIllegalMessageType;
414 }
415
AddBroadcastHandler(const NetlinkMessageHandler & handler)416 bool NetlinkManager::AddBroadcastHandler(const NetlinkMessageHandler& handler) {
417 if (FindBroadcastHandler(handler)) {
418 LOG(WARNING) << "Trying to re-add a handler";
419 return false; // Should only be one copy in the list.
420 }
421 if (handler.is_null()) {
422 LOG(WARNING) << "Trying to add a NULL handler";
423 return false;
424 }
425 // And add the handler to the list.
426 VLOG(3) << "NetlinkManager::" << __func__ << " - adding handler";
427 broadcast_handlers_.push_back(handler);
428 return true;
429 }
430
RemoveBroadcastHandler(const NetlinkMessageHandler & handler)431 bool NetlinkManager::RemoveBroadcastHandler(
432 const NetlinkMessageHandler& handler) {
433 list<NetlinkMessageHandler>::iterator i;
434 for (i = broadcast_handlers_.begin(); i != broadcast_handlers_.end(); ++i) {
435 if ((*i).Equals(handler)) {
436 broadcast_handlers_.erase(i);
437 // Should only be one copy in the list so we don't have to continue
438 // looking for another one.
439 return true;
440 }
441 }
442 LOG(WARNING) << "NetlinkMessageHandler not found.";
443 return false;
444 }
445
FindBroadcastHandler(const NetlinkMessageHandler & handler) const446 bool NetlinkManager::FindBroadcastHandler(const NetlinkMessageHandler& handler)
447 const {
448 for (const auto& broadcast_handler : broadcast_handlers_) {
449 if (broadcast_handler.Equals(handler)) {
450 return true;
451 }
452 }
453 return false;
454 }
455
ClearBroadcastHandlers()456 void NetlinkManager::ClearBroadcastHandlers() {
457 broadcast_handlers_.clear();
458 }
459
SendControlMessage(ControlNetlinkMessage * message,const ControlNetlinkMessageHandler & message_handler,const NetlinkAckHandler & ack_handler,const NetlinkAuxilliaryMessageHandler & error_handler)460 bool NetlinkManager::SendControlMessage(
461 ControlNetlinkMessage* message,
462 const ControlNetlinkMessageHandler& message_handler,
463 const NetlinkAckHandler& ack_handler,
464 const NetlinkAuxilliaryMessageHandler& error_handler) {
465 return SendOrPostMessage(message,
466 new ControlResponseHandler(ack_handler,
467 error_handler,
468 message_handler));
469 }
470
SendNl80211Message(Nl80211Message * message,const Nl80211MessageHandler & message_handler,const NetlinkAckHandler & ack_handler,const NetlinkAuxilliaryMessageHandler & error_handler)471 bool NetlinkManager::SendNl80211Message(
472 Nl80211Message* message,
473 const Nl80211MessageHandler& message_handler,
474 const NetlinkAckHandler& ack_handler,
475 const NetlinkAuxilliaryMessageHandler& error_handler) {
476 return SendOrPostMessage(message,
477 new Nl80211ResponseHandler(ack_handler,
478 error_handler,
479 message_handler));
480 }
481
SendOrPostMessage(NetlinkMessage * message,NetlinkManager::NetlinkResponseHandler * response_handler)482 bool NetlinkManager::SendOrPostMessage(
483 NetlinkMessage* message,
484 NetlinkManager::NetlinkResponseHandler* response_handler) {
485 if (!message) {
486 LOG(ERROR) << "Message is NULL.";
487 return false;
488 }
489
490 const uint32_t sequence_number = this->GetSequenceNumber();
491 const bool is_dump_msg = message->flags() & NLM_F_DUMP;
492 NetlinkPendingMessage pending_message(
493 sequence_number, is_dump_msg, message->Encode(sequence_number),
494 NetlinkResponseHandlerRefPtr(response_handler));
495
496 // TODO(samueltan): print this debug message above the actual call to
497 // NetlinkSocket::SendMessage in NetlinkManager::SendMessageInternal.
498 VLOG(5) << "NL Message " << pending_message.sequence_number << " to send ("
499 << pending_message.message_string.GetLength() << " bytes) ===>";
500 message->Print(6, 7);
501 NetlinkMessage::PrintBytes(8, pending_message.message_string.GetConstData(),
502 pending_message.message_string.GetLength());
503
504 if (is_dump_msg) {
505 pending_messages_.push(pending_message);
506 if (IsDumpPending()) {
507 VLOG(5) << "Dump pending -- will send message after dump is complete";
508 return true;
509 }
510 }
511 return RegisterHandlersAndSendMessage(pending_message);
512 }
513
RegisterHandlersAndSendMessage(const NetlinkPendingMessage & pending_message)514 bool NetlinkManager::RegisterHandlersAndSendMessage(
515 const NetlinkPendingMessage& pending_message) {
516 // Clean out timed-out message handlers. The list of outstanding messages
517 // should be small so the time wasted by looking through all of them should
518 // be small.
519 struct timeval now;
520 time_->GetTimeMonotonic(&now);
521 map<uint32_t, NetlinkResponseHandlerRefPtr>::iterator handler_it =
522 message_handlers_.begin();
523 while (handler_it != message_handlers_.end()) {
524 if (timercmp(&now, &handler_it->second->delete_after(), >)) {
525 // A timeout isn't always unexpected so this is not a warning.
526 VLOG(3) << "Removing timed-out handler for sequence number "
527 << handler_it->first;
528 handler_it->second->HandleError(kTimeoutWaitingForResponse, nullptr);
529 handler_it = message_handlers_.erase(handler_it);
530 } else {
531 ++handler_it;
532 }
533 }
534
535 // Register handlers for replies to this message.
536 if (!pending_message.handler) {
537 VLOG(3) << "Handler for message was null.";
538 } else if (ContainsKey(message_handlers_, pending_message.sequence_number)) {
539 LOG(ERROR) << "A handler already existed for sequence: "
540 << pending_message.sequence_number;
541 return false;
542 } else {
543 struct timeval response_timeout = {kResponseTimeoutSeconds,
544 kResponseTimeoutMicroSeconds};
545 struct timeval delete_after;
546 timeradd(&now, &response_timeout, &delete_after);
547 pending_message.handler->set_delete_after(delete_after);
548
549 message_handlers_[pending_message.sequence_number] =
550 pending_message.handler;
551 }
552 return SendMessageInternal(pending_message);
553 }
554
SendMessageInternal(const NetlinkPendingMessage & pending_message)555 bool NetlinkManager::SendMessageInternal(
556 const NetlinkPendingMessage& pending_message) {
557 VLOG(5) << "Sending NL message " << pending_message.sequence_number;
558
559 if (!sock_->SendMessage(pending_message.message_string)) {
560 LOG(ERROR) << "Failed to send Netlink message.";
561 return false;
562 }
563 if (pending_message.is_dump_request) {
564 VLOG(5) << "Waiting for replies to NL dump message "
565 << pending_message.sequence_number;
566 dump_pending_ = true;
567 pending_dump_timeout_callback_.Reset(Bind(
568 &NetlinkManager::OnPendingDumpTimeout, weak_ptr_factory_.GetWeakPtr()));
569 MessageLoop::current()->PostDelayedTask(
570 FROM_HERE, pending_dump_timeout_callback_.callback(),
571 base::TimeDelta::FromMilliseconds(kPendingDumpTimeoutMilliseconds));
572 }
573 return true;
574 }
575
InferMessageContext(const NetlinkPacket & packet)576 NetlinkMessage::MessageContext NetlinkManager::InferMessageContext(
577 const NetlinkPacket& packet) {
578 NetlinkMessage::MessageContext context;
579
580 const uint32_t sequence_number = packet.GetMessageSequence();
581 if (!ContainsKey(message_handlers_, sequence_number) &&
582 packet.GetMessageType() != ErrorAckMessage::kMessageType) {
583 context.is_broadcast = true;
584 }
585
586 genlmsghdr genl_header;
587 if (packet.GetMessageType() == Nl80211Message::GetMessageType() &&
588 packet.GetGenlMsgHdr(&genl_header)) {
589 context.nl80211_cmd = genl_header.cmd;
590 }
591
592 return context;
593 }
594
OnPendingDumpTimeout()595 void NetlinkManager::OnPendingDumpTimeout() {
596 VLOG(3) << "Timed out waiting for replies to NL dump message "
597 << PendingDumpSequenceNumber();
598 CallErrorHandler(PendingDumpSequenceNumber(), kTimeoutWaitingForResponse,
599 nullptr);
600 OnPendingDumpComplete();
601 }
602
OnPendingDumpComplete()603 void NetlinkManager::OnPendingDumpComplete() {
604 VLOG(3) << __func__;
605 dump_pending_ = false;
606 pending_dump_timeout_callback_.Cancel();
607 resend_dump_message_callback_.Cancel();
608 pending_messages_.pop();
609 if (!pending_messages_.empty()) {
610 VLOG(3) << "Sending next pending message";
611 NetlinkPendingMessage to_send = pending_messages_.front();
612 RegisterHandlersAndSendMessage(to_send);
613 }
614 }
615
IsDumpPending()616 bool NetlinkManager::IsDumpPending() {
617 return dump_pending_ && !pending_messages_.empty();
618 }
619
PendingDumpSequenceNumber()620 uint32_t NetlinkManager::PendingDumpSequenceNumber() {
621 if (!IsDumpPending()) {
622 LOG(ERROR) << __func__ << ": no pending dump";
623 return 0;
624 }
625 return pending_messages_.front().sequence_number;
626 }
627
RemoveMessageHandler(const NetlinkMessage & message)628 bool NetlinkManager::RemoveMessageHandler(const NetlinkMessage& message) {
629 if (!ContainsKey(message_handlers_, message.sequence_number())) {
630 return false;
631 }
632 message_handlers_.erase(message.sequence_number());
633 return true;
634 }
635
GetSequenceNumber()636 uint32_t NetlinkManager::GetSequenceNumber() {
637 return sock_ ?
638 sock_->GetSequenceNumber() : NetlinkMessage::kBroadcastSequenceNumber;
639 }
640
SubscribeToEvents(const string & family_id,const string & group_name)641 bool NetlinkManager::SubscribeToEvents(const string& family_id,
642 const string& group_name) {
643 if (!ContainsKey(message_types_, family_id)) {
644 LOG(ERROR) << "Family '" << family_id << "' doesn't exist";
645 return false;
646 }
647
648 if (!ContainsKey(message_types_[family_id].groups, group_name)) {
649 LOG(ERROR) << "Group '" << group_name << "' doesn't exist in family '"
650 << family_id << "'";
651 return false;
652 }
653
654 uint32_t group_id = message_types_[family_id].groups[group_name];
655 if (!sock_) {
656 LOG(FATAL) << "Need to call |Init| first.";
657 }
658 return sock_->SubscribeToEvents(group_id);
659 }
660
OnRawNlMessageReceived(InputData * data)661 void NetlinkManager::OnRawNlMessageReceived(InputData* data) {
662 if (!data) {
663 LOG(ERROR) << __func__ << "() called with null header.";
664 return;
665 }
666 unsigned char* buf = data->buf;
667 unsigned char* end = buf + data->len;
668 while (buf < end) {
669 NetlinkPacket packet(buf, end - buf);
670 if (!packet.IsValid()) {
671 break;
672 }
673 buf += packet.GetLength();
674 OnNlMessageReceived(&packet);
675 }
676 }
677
OnNlMessageReceived(NetlinkPacket * packet)678 void NetlinkManager::OnNlMessageReceived(NetlinkPacket* packet) {
679 if (!packet) {
680 LOG(ERROR) << __func__ << "() called with null packet.";
681 return;
682 }
683 const uint32_t sequence_number = packet->GetMessageSequence();
684
685 std::unique_ptr<NetlinkMessage> message(
686 message_factory_.CreateMessage(packet, InferMessageContext(*packet)));
687 if (message == nullptr) {
688 VLOG(3) << "NL Message " << sequence_number << " <===";
689 VLOG(3) << __func__ << "(msg:NULL)";
690 return; // Skip current message, continue parsing buffer.
691 }
692 VLOG(5) << "NL Message " << sequence_number << " Received ("
693 << packet->GetLength() << " bytes) <===";
694 message->Print(6, 7);
695 NetlinkMessage::PrintPacket(8, *packet);
696
697 bool is_error_ack_message = false;
698 uint32_t error_code = 0;
699 if (message->message_type() == ErrorAckMessage::GetMessageType()) {
700 is_error_ack_message = true;
701 const ErrorAckMessage* error_ack_message =
702 static_cast<const ErrorAckMessage*>(message.get());
703 error_code = error_ack_message->error();
704 }
705
706 // Note: assumes we only receive one reply to a dump request: an error
707 // message, an ACK, or a single multi-part reply. If we receive two replies,
708 // then we will stop waiting for replies after the first reply is processed
709 // here. This assumption should hold unless the NLM_F_ACK or NLM_F_ECHO
710 // flags are explicitly added to the dump request.
711 if (IsDumpPending() &&
712 (message->sequence_number() == PendingDumpSequenceNumber()) &&
713 !((message->flags() & NLM_F_MULTI) &&
714 (message->message_type() != NLMSG_DONE))) {
715 // Dump currently in progress, this message's sequence number matches that
716 // of the pending dump request, and we are not in the middle of receiving a
717 // multi-part reply.
718 if (is_error_ack_message && (error_code == static_cast<uint32_t>(-EBUSY))) {
719 VLOG(3) << "EBUSY reply received for NL dump message "
720 << PendingDumpSequenceNumber();
721 if (pending_messages_.front().retries_left) {
722 pending_messages_.front().last_received_error = error_code;
723 pending_dump_timeout_callback_.Cancel();
724 ResendPendingDumpMessageAfterDelay();
725 // Since we will resend the message, do not invoke error handler.
726 return;
727 } else {
728 VLOG(3) << "No more resend attempts left for NL dump message "
729 << PendingDumpSequenceNumber() << " -- stop waiting "
730 "for replies";
731 OnPendingDumpComplete();
732 }
733 } else {
734 VLOG(3) << "Reply received for NL dump message "
735 << PendingDumpSequenceNumber() << " -- stop waiting for replies";
736 OnPendingDumpComplete();
737 }
738 }
739
740 if (is_error_ack_message) {
741 VLOG(3) << "Error/ACK response to message " << sequence_number;
742 if (error_code) {
743 CallErrorHandler(sequence_number, kErrorFromKernel, message.get());
744 } else {
745 if (ContainsKey(message_handlers_, sequence_number)) {
746 VLOG(6) << "Found message-specific ACK handler";
747 if (message_handlers_[sequence_number]->HandleAck()) {
748 VLOG(6) << "ACK handler invoked -- removing callback";
749 message_handlers_.erase(sequence_number);
750 } else {
751 VLOG(6) << "ACK handler invoked -- not removing callback";
752 }
753 }
754 }
755 return;
756 }
757
758 if (ContainsKey(message_handlers_, sequence_number)) {
759 VLOG(6) << "Found message-specific handler";
760 if ((message->flags() & NLM_F_MULTI) &&
761 (message->message_type() == NLMSG_DONE)) {
762 message_handlers_[sequence_number]->HandleError(kDone, message.get());
763 } else if (!message_handlers_[sequence_number]->HandleMessage(*message)) {
764 LOG(ERROR) << "Couldn't call message handler for " << sequence_number;
765 // Call the error handler but, since we don't have an |ErrorAckMessage|,
766 // we'll have to pass a nullptr.
767 message_handlers_[sequence_number]->HandleError(kUnexpectedResponseType,
768 nullptr);
769 }
770 if ((message->flags() & NLM_F_MULTI) &&
771 (message->message_type() != NLMSG_DONE)) {
772 VLOG(6) << "Multi-part message -- not removing callback";
773 } else {
774 VLOG(6) << "Removing callbacks";
775 message_handlers_.erase(sequence_number);
776 }
777 return;
778 }
779
780 for (const auto& handler : broadcast_handlers_) {
781 VLOG(6) << "Calling broadcast handler";
782 if (!handler.is_null()) {
783 handler.Run(*message);
784 }
785 }
786 }
787
ResendPendingDumpMessage()788 void NetlinkManager::ResendPendingDumpMessage() {
789 if (!IsDumpPending()) {
790 VLOG(3) << "No pending dump, so do not resend dump message";
791 return;
792 }
793 --pending_messages_.front().retries_left;
794 if (SendMessageInternal(pending_messages_.front())) {
795 VLOG(3) << "NL message " << PendingDumpSequenceNumber()
796 << " sent again successfully";
797 return;
798 }
799 VLOG(3) << "Failed to resend NL message " << PendingDumpSequenceNumber();
800 if (pending_messages_.front().retries_left) {
801 ResendPendingDumpMessageAfterDelay();
802 } else {
803 VLOG(3) << "No more resend attempts left for NL dump message "
804 << PendingDumpSequenceNumber() << " -- stop waiting "
805 "for replies";
806 ErrorAckMessage err_message(pending_messages_.front().last_received_error);
807 CallErrorHandler(PendingDumpSequenceNumber(), kErrorFromKernel,
808 &err_message);
809 OnPendingDumpComplete();
810 }
811 }
812
CallErrorHandler(uint32_t sequence_number,AuxilliaryMessageType type,const NetlinkMessage * netlink_message)813 void NetlinkManager::CallErrorHandler(uint32_t sequence_number,
814 AuxilliaryMessageType type,
815 const NetlinkMessage* netlink_message) {
816 if (ContainsKey(message_handlers_, sequence_number)) {
817 VLOG(6) << "Found message-specific error handler";
818 message_handlers_[sequence_number]->HandleError(type, netlink_message);
819 message_handlers_.erase(sequence_number);
820 }
821 }
822
OnReadError(const string & error_msg)823 void NetlinkManager::OnReadError(const string& error_msg) {
824 // TODO(wdg): When netlink_manager is used for scan, et al., this should
825 // either be LOG(FATAL) or the code should properly deal with errors,
826 // e.g., dropped messages due to the socket buffer being full.
827 LOG(ERROR) << "NetlinkManager's netlink Socket read returns error: "
828 << error_msg;
829 }
830
ResendPendingDumpMessageAfterDelay()831 void NetlinkManager::ResendPendingDumpMessageAfterDelay() {
832 VLOG(3) << "Resending NL dump message " << PendingDumpSequenceNumber()
833 << " after " << kNlMessageRetryDelayMilliseconds << " ms";
834 resend_dump_message_callback_.Reset(
835 Bind(&NetlinkManager::ResendPendingDumpMessage,
836 weak_ptr_factory_.GetWeakPtr()));
837 MessageLoop::current()->PostDelayedTask(
838 FROM_HERE, resend_dump_message_callback_.callback(),
839 base::TimeDelta::FromMilliseconds(kNlMessageRetryDelayMilliseconds));
840 }
841
842 } // namespace shill.
843