#include "FwmarkClient.h"
+#include "FwmarkCommand.h"
+
+#include <errno.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
} // namespace
-bool FwmarkClient::shouldSetFwmark(int sockfd, const sockaddr* addr) {
- return sockfd >= 0 && addr && (addr->sa_family == AF_INET || addr->sa_family == AF_INET6) &&
- !getenv("ANDROID_NO_USE_FWMARK_CLIENT");
+bool FwmarkClient::shouldSetFwmark(int family) {
+ return (family == AF_INET || family == AF_INET6) && !getenv(ANDROID_NO_USE_FWMARK_CLIENT);
+}
+
+bool FwmarkClient::shouldReportConnectComplete(int family) {
+ return shouldSetFwmark(family) && !getenv(ANDROID_FWMARK_METRICS_ONLY);
}
FwmarkClient::FwmarkClient() : mChannel(-1) {
FwmarkClient::~FwmarkClient() {
if (mChannel >= 0) {
- // We don't care about errors while closing the channel, so restore any previous error.
- int error = errno;
close(mChannel);
- errno = error;
}
}
-bool FwmarkClient::send(void* data, size_t len, int fd) {
- mChannel = socket(AF_UNIX, SOCK_STREAM, 0);
+int FwmarkClient::send(FwmarkCommand* data, int fd) {
+ mChannel = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
if (mChannel == -1) {
- return false;
+ return -errno;
}
if (TEMP_FAILURE_RETRY(connect(mChannel, reinterpret_cast<const sockaddr*>(&FWMARK_SERVER_PATH),
sizeof(FWMARK_SERVER_PATH))) == -1) {
// If we are unable to connect to the fwmark server, assume there's no error. This protects
// against future changes if the fwmark server goes away.
- errno = 0;
- return true;
+ return 0;
}
iovec iov;
iov.iov_base = data;
- iov.iov_len = len;
+ iov.iov_len = sizeof(*data);
msghdr message;
memset(&message, 0, sizeof(message));
char cmsg[CMSG_SPACE(sizeof(fd))];
} cmsgu;
- memset(cmsgu.cmsg, 0, sizeof(cmsgu.cmsg));
- message.msg_control = cmsgu.cmsg;
- message.msg_controllen = sizeof(cmsgu.cmsg);
+ if (data->cmdId != FwmarkCommand::QUERY_USER_ACCESS) {
+ memset(cmsgu.cmsg, 0, sizeof(cmsgu.cmsg));
+ message.msg_control = cmsgu.cmsg;
+ message.msg_controllen = sizeof(cmsgu.cmsg);
- cmsghdr* const cmsgh = CMSG_FIRSTHDR(&message);
- cmsgh->cmsg_len = CMSG_LEN(sizeof(fd));
- cmsgh->cmsg_level = SOL_SOCKET;
- cmsgh->cmsg_type = SCM_RIGHTS;
- memcpy(CMSG_DATA(cmsgh), &fd, sizeof(fd));
+ cmsghdr* const cmsgh = CMSG_FIRSTHDR(&message);
+ cmsgh->cmsg_len = CMSG_LEN(sizeof(fd));
+ cmsgh->cmsg_level = SOL_SOCKET;
+ cmsgh->cmsg_type = SCM_RIGHTS;
+ memcpy(CMSG_DATA(cmsgh), &fd, sizeof(fd));
+ }
if (TEMP_FAILURE_RETRY(sendmsg(mChannel, &message, 0)) == -1) {
- return false;
+ return -errno;
}
int error = 0;
+
if (TEMP_FAILURE_RETRY(recv(mChannel, &error, sizeof(error), 0)) == -1) {
- return false;
+ return -errno;
}
- errno = error;
- return !error;
+ return error;
}