Add Syscalls wrapper for writev() and use in XfrmController
Bug:62618292
Test: runtest -x tests/netd_integration_test.cpp
Change-Id: I743c3867aed62d099de6d80bed89e02e11bac5fc
diff --git a/server/XfrmController.cpp b/server/XfrmController.cpp
index 34df936..8437e4b 100644
--- a/server/XfrmController.cpp
+++ b/server/XfrmController.cpp
@@ -49,12 +49,21 @@
#include "NetlinkCommands.h"
#include "ResponseCode.h"
#include "XfrmController.h"
+#include "netdutils/Fd.h"
+#include "netdutils/Slice.h"
+#include "netdutils/Syscalls.h"
#include <cutils/log.h>
#include <cutils/properties.h>
#include <logwrap/logwrap.h>
#define VDBG 1 // STOPSHIP if true
+using android::netdutils::Fd;
+using android::netdutils::Slice;
+using android::netdutils::Status;
+using android::netdutils::StatusOr;
+using android::netdutils::Syscalls;
+
namespace android {
namespace net {
@@ -142,6 +151,8 @@
}
}
+inline Syscalls& getSyscallInstance() { return netdutils::sSyscalls.get(); }
+
#else
#define LOG_HEX(__desc16__, __buf__, __len__)
#define LOG_IOV(__iov__, __iov_len__)
@@ -220,32 +231,44 @@
nlMsg.nlmsg_len += iov[i].iov_len;
}
+ // TODO: Should use std::vector<iovec> from the beginning, should
+ // replace the iovec array declaration with an iovec vector declaration
+ // in other places of the program.
+ // This line should be removed when the parameter of sendMessage is
+ // changed to use iovev vector.
+ const std::vector<iovec> iovs(iov, iov + iovLen);
+
ALOGD("Sending Netlink XFRM Message: %s", xfrmMsgTypeToString(nlMsgType));
if (VDBG)
LOG_IOV(iov, iovLen);
- int ret;
-
- if (writev(mSock, iov, iovLen) < 0) {
- ALOGE("netlink socket writev failed (%s)", strerror(errno));
- return -errno;
+ StatusOr<size_t> writeResult = getSyscallInstance().writev(mSock, iovs);
+ if (!isOk(writeResult)) {
+ ALOGE("netlink socket writev failed (%s)", toString(writeResult).c_str());
+ return -writeResult.status().code();
}
- NetlinkResponse* response = new NetlinkResponse{};
-
- if ((ret = recv(mSock, response, sizeof(*response), 0)) < 0) {
- ALOGE("netlink response contains error (%s)", strerror(errno));
- delete response;
- return -errno;
+ if (nlMsg.nlmsg_len != writeResult.value()) {
+ ALOGE("Invalid netlink message length sent %d", static_cast<int>(writeResult.value()));
+ return -EBADMSG;
}
- LOG_HEX("netlink msg resp", reinterpret_cast<char*>(response), ret);
+ NetlinkResponse response = {};
- ret = validateResponse(*response, ret);
- delete response;
- if (ret < 0)
- ALOGE("netlink response contains error (%s)", strerror(-ret));
- return ret;
+ StatusOr<Slice> readResult =
+ getSyscallInstance().read(Fd(mSock), netdutils::makeSlice(response));
+ if (!isOk(readResult)) {
+ ALOGE("netlink response error (%s)", toString(readResult).c_str());
+ return -readResult.status().code();
+ }
+
+ LOG_HEX("netlink msg resp", reinterpret_cast<char*>(readResult.value().base()),
+ readResult.value().size());
+
+ int retNum = validateResponse(response, readResult.value().size());
+ if (retNum < 0)
+ ALOGE("netlink response contains error (%s)", strerror(-retNum));
+ return retNum;
}
};
@@ -535,15 +558,16 @@
struct sockaddr_storage saddr;
- socklen_t len = sizeof(saddr);
int err;
- int userSocket = socket.get();
- if ((err = getsockname(userSocket, reinterpret_cast<struct sockaddr*>(&saddr), &len)) < 0) {
+ StatusOr<sockaddr_storage> ret = getSyscallInstance().getsockname<sockaddr_storage>(Fd(socket));
+ if (!isOk(ret)) {
ALOGE("Failed to get socket info in %s", __FUNCTION__);
- return -err;
+ return -ret.status().code();
}
+ saddr = ret.value();
+
XfrmSaInfo saInfo{};
saInfo.transformId = transformId;
saInfo.direction = static_cast<XfrmDirection>(direction);
@@ -585,13 +609,11 @@
return -EAFNOSUPPORT;
}
- err = setsockopt(userSocket, sockLayer, sockOpt, &policy, sizeof(policy));
- if (err < 0) {
- err = errno;
- ALOGE("Error setting socket option for XFRM! (%s)", strerror(err));
+ Status status = getSyscallInstance().setsockopt(Fd(socket), sockLayer, sockOpt, policy);
+ if (!isOk(status)) {
+ ALOGE("Error setting socket option for XFRM! (%s)", toString(status).c_str());
}
-
- return -err;
+ return -status.code();
}
int XfrmController::ipSecRemoveTransportModeTransform(const android::base::unique_fd& socket) {