blob: 5bf49fda546440b7a0d5867db86a2c2c4380fd5c [file] [log] [blame]
Ben Chanfad4a0b2012-04-18 15:49:59 -07001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Darin Petkov50308cd2011-06-01 18:25:07 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/dhcpcd_proxy.h"
6
Paul Stewart3095c072012-12-14 08:05:07 -08007#include <dbus/dbus.h>
8#include <string.h>
9
Christopher Wileyb691efd2012-08-09 13:51:51 -070010#include <limits>
Darin Petkov50308cd2011-06-01 18:25:07 -070011
Darin Petkovd1b715b2011-06-02 21:21:22 -070012#include "shill/dhcp_provider.h"
Christopher Wileyb691efd2012-08-09 13:51:51 -070013#include "shill/logging.h"
Darin Petkovd1b715b2011-06-02 21:21:22 -070014
15using std::string;
Darin Petkove7cb7f82011-06-03 13:21:51 -070016using std::vector;
Darin Petkovd1b715b2011-06-02 21:21:22 -070017
Darin Petkov50308cd2011-06-01 18:25:07 -070018namespace shill {
19
20const char DHCPCDProxy::kDBusInterfaceName[] = "org.chromium.dhcpcd";
21const char DHCPCDProxy::kDBusPath[] = "/org/chromium/dhcpcd";
22
Darin Petkovaceede32011-07-18 15:32:38 -070023DHCPCDListener::DHCPCDListener(DBus::Connection *connection,
24 DHCPProvider *provider)
25 : proxy_(connection, provider) {}
26
27DHCPCDListener::Proxy::Proxy(DBus::Connection *connection,
28 DHCPProvider *provider)
Darin Petkov50308cd2011-06-01 18:25:07 -070029 : DBus::InterfaceProxy(DHCPCDProxy::kDBusInterfaceName),
Darin Petkovd1b715b2011-06-02 21:21:22 -070030 DBus::ObjectProxy(*connection, DHCPCDProxy::kDBusPath),
31 provider_(provider) {
Ben Chanfad4a0b2012-04-18 15:49:59 -070032 SLOG(DHCP, 2) << __func__;
Darin Petkovaceede32011-07-18 15:32:38 -070033 connect_signal(DHCPCDListener::Proxy, Event, EventSignal);
34 connect_signal(DHCPCDListener::Proxy, StatusChanged, StatusChangedSignal);
Darin Petkov50308cd2011-06-01 18:25:07 -070035}
36
Darin Petkovaceede32011-07-18 15:32:38 -070037void DHCPCDListener::Proxy::EventSignal(const DBus::SignalMessage &signal) {
mukesh agrawal06175d72012-04-23 16:46:01 -070038 SLOG(DBus, 2) << __func__;
Darin Petkov50308cd2011-06-01 18:25:07 -070039 DBus::MessageIter ri = signal.reader();
Christopher Wileyb691efd2012-08-09 13:51:51 -070040 unsigned int pid = std::numeric_limits<unsigned int>::max();
Gary Morain610977f2012-05-04 16:03:52 -070041 try {
42 ri >> pid;
43 } catch (const DBus::Error &e) {
44 LOG(FATAL) << "DBus exception: " << e.name() << ": " << e.what()
45 << " interface: " << signal.interface()
46 << " member: " << signal.member() << " path: " << signal.path();
47 }
Ben Chanfad4a0b2012-04-18 15:49:59 -070048 SLOG(DHCP, 2) << "sender(" << signal.sender() << ") pid(" << pid << ")";
Darin Petkovd1b715b2011-06-02 21:21:22 -070049
50 DHCPConfigRefPtr config = provider_->GetConfig(pid);
51 if (!config.get()) {
52 LOG(ERROR) << "Unknown DHCP client PID " << pid;
53 return;
54 }
Darin Petkovaceede32011-07-18 15:32:38 -070055 config->InitProxy(signal.sender());
Darin Petkove7cb7f82011-06-03 13:21:51 -070056
57 string reason;
Gary Morain610977f2012-05-04 16:03:52 -070058 try {
Darin Petkove7cb7f82011-06-03 13:21:51 -070059 ri >> reason;
Gary Morain610977f2012-05-04 16:03:52 -070060 } catch (const DBus::Error &e) {
61 LOG(FATAL) << "DBus exception: " << e.name() << ": " << e.what()
62 << " interface: " << signal.interface()
63 << " member: " << signal.member() << " path: " << signal.path();
64 }
Darin Petkove7cb7f82011-06-03 13:21:51 -070065 DHCPConfig::Configuration configuration;
Gary Morain610977f2012-05-04 16:03:52 -070066 try {
67 ri >> configuration;
68 } catch (const DBus::Error &e) {
69 LOG(FATAL) << "DBus exception: " << e.name() << ": " << e.what()
70 << " interface: " << signal.interface()
71 << " member: " << signal.member() << " path: " << signal.path();
72 }
Darin Petkove7cb7f82011-06-03 13:21:51 -070073 config->ProcessEventSignal(reason, configuration);
Darin Petkov50308cd2011-06-01 18:25:07 -070074}
75
Darin Petkovaceede32011-07-18 15:32:38 -070076void DHCPCDListener::Proxy::StatusChangedSignal(
77 const DBus::SignalMessage &signal) {
mukesh agrawal06175d72012-04-23 16:46:01 -070078 SLOG(DBus, 2) << __func__;
Darin Petkov50308cd2011-06-01 18:25:07 -070079 DBus::MessageIter ri = signal.reader();
Christopher Wileyb691efd2012-08-09 13:51:51 -070080 unsigned int pid = std::numeric_limits<unsigned int>::max();
Gary Morain610977f2012-05-04 16:03:52 -070081 try {
82 ri >> pid;
83 } catch (const DBus::Error &e) {
84 LOG(FATAL) << "DBus exception: " << e.name() << ": " << e.what()
85 << " interface: " << signal.interface()
86 << " member: " << signal.member() << " path: " << signal.path();
87 }
Ben Chanfad4a0b2012-04-18 15:49:59 -070088 SLOG(DHCP, 2) << "sender(" << signal.sender() << ") pid(" << pid << ")";
Darin Petkovd1b715b2011-06-02 21:21:22 -070089
90 // Accept StatusChanged signals just to get the sender address and create an
91 // appropriate proxy for the PID/sender pair.
92 DHCPConfigRefPtr config = provider_->GetConfig(pid);
93 if (!config.get()) {
94 LOG(ERROR) << "Unknown DHCP client PID " << pid;
95 return;
96 }
Darin Petkovaceede32011-07-18 15:32:38 -070097 config->InitProxy(signal.sender());
Darin Petkov50308cd2011-06-01 18:25:07 -070098}
99
Darin Petkova7b89492011-07-27 12:48:17 -0700100DHCPCDProxy::DHCPCDProxy(DBus::Connection *connection, const string &service)
Darin Petkovaceede32011-07-18 15:32:38 -0700101 : proxy_(connection, service) {
Ben Chanfad4a0b2012-04-18 15:49:59 -0700102 SLOG(DHCP, 2) << "DHCPCDProxy(service=" << service << ").";
Darin Petkovaceede32011-07-18 15:32:38 -0700103}
Darin Petkov50308cd2011-06-01 18:25:07 -0700104
Darin Petkovaceede32011-07-18 15:32:38 -0700105void DHCPCDProxy::Rebind(const string &interface) {
mukesh agrawal06175d72012-04-23 16:46:01 -0700106 SLOG(DBus, 2) << __func__;
Gary Morain610977f2012-05-04 16:03:52 -0700107 try {
108 proxy_.Rebind(interface);
109 } catch (const DBus::Error &e) {
110 LOG(FATAL) << "DBus exception: " << e.name() << ": " << e.what()
111 << " interface: " << interface;
112 }
Darin Petkovaceede32011-07-18 15:32:38 -0700113}
114
115void DHCPCDProxy::Release(const string &interface) {
mukesh agrawal06175d72012-04-23 16:46:01 -0700116 SLOG(DBus, 2) << __func__;
Gary Morain610977f2012-05-04 16:03:52 -0700117 try {
118 proxy_.Release(interface);
119 } catch (const DBus::Error &e) {
Paul Stewart3095c072012-12-14 08:05:07 -0800120 if (!strcmp(e.name(), DBUS_ERROR_SERVICE_UNKNOWN)) {
121 LOG(ERROR) << "dhcpcd daemon appears to have already exited.";
122 } else {
123 LOG(FATAL) << "DBus exception: " << e.name() << ": " << e.what()
124 << " interface: " << interface;
125 }
Gary Morain610977f2012-05-04 16:03:52 -0700126 }
Darin Petkovaceede32011-07-18 15:32:38 -0700127}
128
129DHCPCDProxy::Proxy::Proxy(DBus::Connection *connection,
Darin Petkova7b89492011-07-27 12:48:17 -0700130 const string &service)
131 : DBus::ObjectProxy(*connection, kDBusPath, service.c_str()) {
Darin Petkov50308cd2011-06-01 18:25:07 -0700132 // Don't catch signals directly in this proxy because they will be dispatched
Darin Petkovaceede32011-07-18 15:32:38 -0700133 // to the client by the DHCPCD listener.
Darin Petkov50308cd2011-06-01 18:25:07 -0700134 _signals.erase("Event");
135 _signals.erase("StatusChanged");
136}
137
Darin Petkova7b89492011-07-27 12:48:17 -0700138DHCPCDProxy::Proxy::~Proxy() {}
139
mukesh agrawal1830fa12011-09-26 14:31:40 -0700140void DHCPCDProxy::Proxy::Event(
141 const uint32_t &/*pid*/,
142 const std::string &/*reason*/,
143 const DHCPConfig::Configuration &/*configuration*/) {
mukesh agrawal06175d72012-04-23 16:46:01 -0700144 SLOG(DBus, 2) << __func__;
Darin Petkovd1b715b2011-06-02 21:21:22 -0700145 NOTREACHED();
Darin Petkov50308cd2011-06-01 18:25:07 -0700146}
147
mukesh agrawal1830fa12011-09-26 14:31:40 -0700148void DHCPCDProxy::Proxy::StatusChanged(const uint32_t &/*pid*/,
149 const std::string &/*status*/) {
mukesh agrawal06175d72012-04-23 16:46:01 -0700150 SLOG(DBus, 2) << __func__;
Darin Petkovd1b715b2011-06-02 21:21:22 -0700151 NOTREACHED();
Darin Petkov50308cd2011-06-01 18:25:07 -0700152}
153
154} // namespace shill