Replace useCanSockets hack with flexible per-process domain selection
Bug: 158011272
Test: manual
Change-Id: I29d88a42e2309483a740cde9f9a463d83c7a560c
diff --git a/automotive/can/1.0/default/libnetdevice/common.cpp b/automotive/can/1.0/default/libnetdevice/common.cpp
index 387c91f..f2968fc 100644
--- a/automotive/can/1.0/default/libnetdevice/common.cpp
+++ b/automotive/can/1.0/default/libnetdevice/common.cpp
@@ -22,8 +22,6 @@
namespace android::netdevice {
-socketparams::Params socketparams::current = general;
-
unsigned int nametoindex(const std::string& ifname) {
const auto ifidx = if_nametoindex(ifname.c_str());
if (ifidx != 0) return ifidx;
diff --git a/automotive/can/1.0/default/libnetdevice/common.h b/automotive/can/1.0/default/libnetdevice/common.h
index b4f91bd..1e0d5b7 100644
--- a/automotive/can/1.0/default/libnetdevice/common.h
+++ b/automotive/can/1.0/default/libnetdevice/common.h
@@ -25,21 +25,6 @@
namespace android::netdevice {
-namespace socketparams {
-
-struct Params {
- int domain;
- int type;
- int protocol;
-};
-
-constexpr Params general = {AF_INET, SOCK_DGRAM, 0};
-constexpr Params can = {PF_CAN, SOCK_RAW, CAN_RAW};
-
-extern Params current;
-
-} // namespace socketparams
-
/**
* Returns the index of a given network interface.
*
diff --git a/automotive/can/1.0/default/libnetdevice/ifreqs.cpp b/automotive/can/1.0/default/libnetdevice/ifreqs.cpp
index 9335021..8df6434 100644
--- a/automotive/can/1.0/default/libnetdevice/ifreqs.cpp
+++ b/automotive/can/1.0/default/libnetdevice/ifreqs.cpp
@@ -21,11 +21,35 @@
#include <android-base/logging.h>
#include <android-base/unique_fd.h>
+#include <map>
+
namespace android::netdevice::ifreqs {
+static constexpr int defaultSocketDomain = AF_INET;
+std::atomic_int socketDomain = defaultSocketDomain;
+
+struct SocketParams {
+ int domain;
+ int type;
+ int protocol;
+};
+
+static const std::map<int, SocketParams> socketParams = {
+ {AF_INET, {AF_INET, SOCK_DGRAM, 0}},
+ {AF_CAN, {AF_CAN, SOCK_RAW, CAN_RAW}},
+};
+
+static SocketParams getSocketParams(int domain) {
+ if (socketParams.count(domain)) return socketParams.find(domain)->second;
+
+ auto params = socketParams.find(defaultSocketDomain)->second;
+ params.domain = domain;
+ return params;
+}
+
bool send(unsigned long request, struct ifreq& ifr) {
- base::unique_fd sock(socket(socketparams::current.domain, socketparams::current.type,
- socketparams::current.protocol));
+ const auto sp = getSocketParams(socketDomain);
+ base::unique_fd sock(socket(sp.domain, sp.type, sp.protocol));
if (!sock.ok()) {
LOG(ERROR) << "Can't create socket";
return false;
diff --git a/automotive/can/1.0/default/libnetdevice/ifreqs.h b/automotive/can/1.0/default/libnetdevice/ifreqs.h
index 25a40a6..74e5877 100644
--- a/automotive/can/1.0/default/libnetdevice/ifreqs.h
+++ b/automotive/can/1.0/default/libnetdevice/ifreqs.h
@@ -23,6 +23,11 @@
namespace android::netdevice::ifreqs {
/**
+ * \see useSocketDomain()
+ */
+extern std::atomic_int socketDomain;
+
+/**
* Sends ioctl interface request.
*
* \param request Request type (such as SIOCGIFFLAGS)
diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h
index 037618a..9a26ff1 100644
--- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h
+++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h
@@ -27,15 +27,14 @@
typedef std::array<uint8_t, ETH_ALEN> hwaddr_t;
/**
- * Configures libnetdevice to use PF_CAN sockets instead of AF_INET,
+ * Configures libnetdevice to use other socket domain than AF_INET,
* what requires less permissive SEPolicy rules for a given process.
*
- * In such case, the process would only be able to control CAN interfaces.
- *
- * TODO(b/158011272): consider less hacky solution
- * \param yes true to use CAN sockets, false for general sockets
+ * In such case, the process would only be able to control interfaces of a given kind.
+
+ * \param domain Socket domain to use (e.g. AF_CAN), see socket(2) for details
*/
-void useCanSockets(bool yes);
+void useSocketDomain(int domain);
/**
* Checks, if the network interface exists.
diff --git a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp
index 4bba5f6..4293cad 100644
--- a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp
+++ b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp
@@ -28,8 +28,8 @@
namespace android::netdevice {
-void useCanSockets(bool yes) {
- socketparams::current = yes ? socketparams::can : socketparams::general;
+void useSocketDomain(int domain) {
+ ifreqs::socketDomain = domain;
}
bool exists(std::string ifname) {
diff --git a/automotive/can/1.0/default/service.cpp b/automotive/can/1.0/default/service.cpp
index b5801c0..9a9d322 100644
--- a/automotive/can/1.0/default/service.cpp
+++ b/automotive/can/1.0/default/service.cpp
@@ -28,7 +28,7 @@
configureRpcThreadpool(16, true);
LOG(DEBUG) << "CAN controller service starting...";
- netdevice::useCanSockets(true);
+ netdevice::useSocketDomain(AF_CAN);
sp<CanController> canController(new CanController);
if (canController->registerAsService("socketcan") != OK) {