diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-12-02 20:07:20 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-12-02 20:07:20 +0000 |
commit | 2f20c723b4f8ef8e8380d57a7b95fb7d0deaf204 (patch) | |
tree | da0147ccc8504b0c4f154b9797a511a4dc98b9fb | |
parent | 89e829d28ef73f6f96a7a0097ac10939a9e3d3f5 (diff) | |
parent | b91d1409c3047ba954780fa3c548d939323ea372 (diff) | |
download | netd-android12-mainline-mediaprovider-release.tar.gz |
Snap for 7963901 from b91d1409c3047ba954780fa3c548d939323ea372 to mainline-mediaprovider-releaseandroid-mainline-12.0.0_r90android-mainline-12.0.0_r76android-mainline-12.0.0_r121android-mainline-12.0.0_r106aml_mpr_311911090android12-mainline-mediaprovider-release
Change-Id: I3aa5fb25cba5dc7cafc83960bd40f44fcbba3f23
50 files changed, 3 insertions, 5261 deletions
diff --git a/bpf_progs/Android.bp b/bpf_progs/Android.bp index 1311ca90..35a74b84 100644 --- a/bpf_progs/Android.bp +++ b/bpf_progs/Android.bp @@ -39,8 +39,8 @@ bpf { "-Werror", ], include_dirs: [ + "frameworks/libs/net/common/netd/libnetdutils/include", "system/netd/libnetdbpf/include", - "system/netd/libnetdutils/include", ], } @@ -52,7 +52,7 @@ bpf { "-Werror", ], include_dirs: [ + "frameworks/libs/net/common/netd/libnetdutils/include", "system/netd/libnetdbpf/include", - "system/netd/libnetdutils/include", ], } diff --git a/client/Android.bp b/client/Android.bp index b8eb56c4..1a6114b4 100644 --- a/client/Android.bp +++ b/client/Android.bp @@ -34,7 +34,7 @@ cc_library { ], export_header_lib_headers: ["libnetd_client_headers"], include_dirs: [ - "system/netd/libnetdutils/include", + "frameworks/libs/net/common/netd/libnetdutils/include", ], defaults: ["netd_defaults"], sanitize: { diff --git a/libnetdutils/Android.bp b/libnetdutils/Android.bp deleted file mode 100644 index 31f2c53b..00000000 --- a/libnetdutils/Android.bp +++ /dev/null @@ -1,70 +0,0 @@ -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "system_netd_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["system_netd_license"], -} - -cc_library { - name: "libnetdutils", - srcs: [ - "DumpWriter.cpp", - "Fd.cpp", - "InternetAddresses.cpp", - "Log.cpp", - "Netfilter.cpp", - "Netlink.cpp", - "Slice.cpp", - "Socket.cpp", - "SocketOption.cpp", - "Status.cpp", - "Syscalls.cpp", - "UniqueFd.cpp", - "UniqueFile.cpp", - ], - defaults: ["netd_defaults"], - cflags: ["-Wall", "-Werror"], - shared_libs: [ - "libbase", - "liblog", - ], - export_shared_lib_headers: [ - "libbase", - ], - export_include_dirs: ["include"], - sanitize: { - cfi: true, - }, - - apex_available: [ - "//apex_available:platform", - "com.android.resolv", - ], - min_sdk_version: "29", -} - -cc_test { - name: "netdutils_test", - srcs: [ - "BackoffSequenceTest.cpp", - "FdTest.cpp", - "InternetAddressesTest.cpp", - "LogTest.cpp", - "MemBlockTest.cpp", - "SliceTest.cpp", - "StatusTest.cpp", - "SyscallsTest.cpp", - "ThreadUtilTest.cpp", - ], - defaults: ["netd_defaults"], - test_suites: ["device-tests"], - static_libs: [ - "libgmock", - "libnetdutils", - ], - shared_libs: [ - "libbase", - ], -} diff --git a/libnetdutils/BackoffSequenceTest.cpp b/libnetdutils/BackoffSequenceTest.cpp deleted file mode 100644 index b6653fe8..00000000 --- a/libnetdutils/BackoffSequenceTest.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <gtest/gtest.h> - -#include "netdutils/BackoffSequence.h" - -namespace android { -namespace netdutils { - -TEST(BackoffSequence, defaults) { - BackoffSequence<uint32_t> backoff; - - EXPECT_TRUE(backoff.hasNextTimeout()); - EXPECT_EQ(0x00000001U, backoff.getNextTimeout()); - EXPECT_EQ(0x00000002U, backoff.getNextTimeout()); - EXPECT_EQ(0x00000004U, backoff.getNextTimeout()); - EXPECT_EQ(0x00000008U, backoff.getNextTimeout()); - EXPECT_EQ(0x00000010U, backoff.getNextTimeout()); - EXPECT_EQ(0x00000020U, backoff.getNextTimeout()); - EXPECT_EQ(0x00000040U, backoff.getNextTimeout()); - EXPECT_EQ(0x00000080U, backoff.getNextTimeout()); - EXPECT_EQ(0x00000100U, backoff.getNextTimeout()); - EXPECT_EQ(0x00000200U, backoff.getNextTimeout()); - EXPECT_EQ(0x00000400U, backoff.getNextTimeout()); - EXPECT_EQ(0x00000800U, backoff.getNextTimeout()); - EXPECT_EQ(0x00001000U, backoff.getNextTimeout()); - EXPECT_EQ(0x00002000U, backoff.getNextTimeout()); - EXPECT_EQ(0x00004000U, backoff.getNextTimeout()); - EXPECT_EQ(0x00008000U, backoff.getNextTimeout()); - EXPECT_EQ(0x00010000U, backoff.getNextTimeout()); - EXPECT_EQ(0x00020000U, backoff.getNextTimeout()); - EXPECT_EQ(0x00040000U, backoff.getNextTimeout()); - EXPECT_EQ(0x00080000U, backoff.getNextTimeout()); - EXPECT_EQ(0x00100000U, backoff.getNextTimeout()); - EXPECT_EQ(0x00200000U, backoff.getNextTimeout()); - EXPECT_EQ(0x00400000U, backoff.getNextTimeout()); - EXPECT_EQ(0x00800000U, backoff.getNextTimeout()); - EXPECT_EQ(0x01000000U, backoff.getNextTimeout()); - EXPECT_EQ(0x02000000U, backoff.getNextTimeout()); - EXPECT_EQ(0x04000000U, backoff.getNextTimeout()); - EXPECT_EQ(0x08000000U, backoff.getNextTimeout()); - EXPECT_EQ(0x10000000U, backoff.getNextTimeout()); - EXPECT_EQ(0x20000000U, backoff.getNextTimeout()); - EXPECT_EQ(0x40000000U, backoff.getNextTimeout()); - EXPECT_EQ(0x80000000U, backoff.getNextTimeout()); - // Maxes out, and stays there, ad infinitum. - for (int i = 0; i < 10; i++) { - EXPECT_TRUE(backoff.hasNextTimeout()); - EXPECT_EQ(0xffffffffU, backoff.getNextTimeout()); - } -} - -TEST(BackoffSequence, backoffToOncePerHour) { - auto backoff = BackoffSequence<uint32_t>::Builder() - .withInitialRetransmissionTime(1) - .withMaximumRetransmissionTime(3600) - .build(); - - EXPECT_TRUE(backoff.hasNextTimeout()); - EXPECT_EQ(0x00000001U, backoff.getNextTimeout()); - EXPECT_EQ(0x00000002U, backoff.getNextTimeout()); - EXPECT_EQ(0x00000004U, backoff.getNextTimeout()); - EXPECT_EQ(0x00000008U, backoff.getNextTimeout()); - EXPECT_EQ(0x00000010U, backoff.getNextTimeout()); - EXPECT_EQ(0x00000020U, backoff.getNextTimeout()); - EXPECT_EQ(0x00000040U, backoff.getNextTimeout()); - EXPECT_EQ(0x00000080U, backoff.getNextTimeout()); - EXPECT_EQ(0x00000100U, backoff.getNextTimeout()); - EXPECT_EQ(0x00000200U, backoff.getNextTimeout()); - EXPECT_EQ(0x00000400U, backoff.getNextTimeout()); - EXPECT_EQ(0x00000800U, backoff.getNextTimeout()); - // Maxes out, and stays there, ad infinitum. - for (int i = 0; i < 10; i++) { - EXPECT_TRUE(backoff.hasNextTimeout()); - EXPECT_EQ(3600U, backoff.getNextTimeout()); - } -} - -TEST(BackoffSequence, simpleMaxRetransCount) { - auto backoff = BackoffSequence<uint32_t>::Builder() - .withInitialRetransmissionTime(3) - .withMaximumRetransmissionCount(7) - .build(); - - EXPECT_TRUE(backoff.hasNextTimeout()); - EXPECT_EQ(0x00000003U, backoff.getNextTimeout()); - EXPECT_EQ(0x00000006U, backoff.getNextTimeout()); - EXPECT_EQ(0x0000000cU, backoff.getNextTimeout()); - EXPECT_EQ(0x00000018U, backoff.getNextTimeout()); - EXPECT_EQ(0x00000030U, backoff.getNextTimeout()); - EXPECT_EQ(0x00000060U, backoff.getNextTimeout()); - EXPECT_EQ(0x000000c0U, backoff.getNextTimeout()); - - for (int i = 0; i < 10; i++) { - EXPECT_FALSE(backoff.hasNextTimeout()); - EXPECT_EQ(backoff.getEndOfSequenceIndicator(), backoff.getNextTimeout()); - } -} - -TEST(BackoffSequence, simpleMaxDuration) { - auto backoff = BackoffSequence<int>::Builder() - .withInitialRetransmissionTime(3) - .withMaximumRetransmissionDuration(7) - .withEndOfSequenceIndicator(-1) - .build(); - - EXPECT_TRUE(backoff.hasNextTimeout()); - EXPECT_EQ(0x00000003, backoff.getNextTimeout()); - EXPECT_EQ(0x00000004, backoff.getNextTimeout()); - - for (int i = 0; i < 10; i++) { - EXPECT_FALSE(backoff.hasNextTimeout()); - EXPECT_EQ(backoff.getEndOfSequenceIndicator(), backoff.getNextTimeout()); - EXPECT_EQ(-1, backoff.getNextTimeout()); - } -} - -TEST(PathologicalBackoffSequence, ZeroInitialRetransTime) { - auto backoff = BackoffSequence<std::chrono::seconds>::Builder() - .withInitialRetransmissionTime(std::chrono::seconds(0)) - .build(); - - for (int i = 0; i < 10; i++) { - // TODO: Decide whether this needs fixing, and how. - EXPECT_TRUE(backoff.hasNextTimeout()); - EXPECT_EQ(backoff.getEndOfSequenceIndicator(), backoff.getNextTimeout()); - } -} - -TEST(PathologicalBackoffSequence, MaxRetransDurationGreaterThanInitialRetransTime) { - auto backoff = BackoffSequence<std::chrono::milliseconds>::Builder() - .withInitialRetransmissionTime(std::chrono::milliseconds(5)) - .withMaximumRetransmissionDuration(std::chrono::milliseconds(3)) - .build(); - - EXPECT_EQ(std::chrono::milliseconds(3), backoff.getNextTimeout()); - for (int i = 0; i < 10; i++) { - EXPECT_FALSE(backoff.hasNextTimeout()); - EXPECT_EQ(backoff.getEndOfSequenceIndicator(), backoff.getNextTimeout()); - } -} - -TEST(PathologicalBackoffSequence, MaxRetransDurationEqualsInitialRetransTime) { - auto backoff = BackoffSequence<std::chrono::hours>::Builder() - .withInitialRetransmissionTime(std::chrono::hours(5)) - .withMaximumRetransmissionDuration(std::chrono::hours(5)) - .build(); - - EXPECT_EQ(std::chrono::hours(5), backoff.getNextTimeout()); - for (int i = 0; i < 10; i++) { - EXPECT_FALSE(backoff.hasNextTimeout()); - EXPECT_EQ(backoff.getEndOfSequenceIndicator(), backoff.getNextTimeout()); - } -} - -TEST(PathologicalBackoffSequence, MaxRetransTimeAndDurationGreaterThanInitialRetransTime) { - auto backoff = BackoffSequence<std::chrono::nanoseconds>::Builder() - .withInitialRetransmissionTime(std::chrono::nanoseconds(7)) - .withMaximumRetransmissionTime(std::chrono::nanoseconds(3)) - .withMaximumRetransmissionDuration(std::chrono::nanoseconds(5)) - .build(); - - EXPECT_EQ(std::chrono::nanoseconds(3), backoff.getNextTimeout()); - EXPECT_EQ(std::chrono::nanoseconds(2), backoff.getNextTimeout()); - for (int i = 0; i < 10; i++) { - EXPECT_FALSE(backoff.hasNextTimeout()); - EXPECT_EQ(backoff.getEndOfSequenceIndicator(), backoff.getNextTimeout()); - } -} - -} // namespace netdutils -} // namespace android diff --git a/libnetdutils/DumpWriter.cpp b/libnetdutils/DumpWriter.cpp deleted file mode 100644 index 092ddbae..00000000 --- a/libnetdutils/DumpWriter.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "netdutils/DumpWriter.h" - -#include <unistd.h> -#include <limits> - -#include <android-base/stringprintf.h> -#include <utils/String8.h> - -using android::base::StringAppendV; - -namespace android { -namespace netdutils { - -namespace { - -const char kIndentString[] = " "; -const size_t kIndentStringLen = strlen(kIndentString); - -} // namespace - -DumpWriter::DumpWriter(int fd) : mIndentLevel(0), mFd(fd) {} - -void DumpWriter::incIndent() { - if (mIndentLevel < std::numeric_limits<decltype(mIndentLevel)>::max()) { - mIndentLevel++; - } -} - -void DumpWriter::decIndent() { - if (mIndentLevel > std::numeric_limits<decltype(mIndentLevel)>::min()) { - mIndentLevel--; - } -} - -void DumpWriter::println(const std::string& line) { - if (!line.empty()) { - for (int i = 0; i < mIndentLevel; i++) { - ::write(mFd, kIndentString, kIndentStringLen); - } - ::write(mFd, line.c_str(), line.size()); - } - ::write(mFd, "\n", 1); -} - -// NOLINTNEXTLINE(cert-dcl50-cpp): Grandfathered C-style variadic function. -void DumpWriter::println(const char* fmt, ...) { - std::string line; - va_list ap; - va_start(ap, fmt); - StringAppendV(&line, fmt, ap); - va_end(ap); - println(line); -} - -} // namespace netdutils -} // namespace android diff --git a/libnetdutils/Fd.cpp b/libnetdutils/Fd.cpp deleted file mode 100644 index 2651f906..00000000 --- a/libnetdutils/Fd.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "netdutils/Fd.h" - -namespace android { -namespace netdutils { - -std::ostream& operator<<(std::ostream& os, const Fd& fd) { - return os << "Fd[" << fd.get() << "]"; -} - -} // namespace netdutils -} // namespace android diff --git a/libnetdutils/FdTest.cpp b/libnetdutils/FdTest.cpp deleted file mode 100644 index 7080f831..00000000 --- a/libnetdutils/FdTest.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <cstdint> - -#include <gtest/gtest.h> - -#include "netdutils/MockSyscalls.h" -#include "netdutils/Status.h" -#include "netdutils/Syscalls.h" - -using testing::Mock; -using testing::Return; -using testing::StrictMock; - -namespace android { -namespace netdutils { -namespace { - -// Force implicit conversion from UniqueFd -> Fd -inline Fd toFd(const UniqueFd& fd) { - return fd; -} - -} // namespace - -TEST(Fd, smoke) { - // Expect the following lines to compile - Fd fd1(1); - Fd fd2(fd1); - Fd fd3 = fd2; - const Fd fd4(8); - const Fd fd5(fd4); - const Fd fd6 = fd5; - EXPECT_TRUE(isWellFormed(fd3)); - EXPECT_TRUE(isWellFormed(fd6)); - - // Corner case - Fd zero(0); - EXPECT_TRUE(isWellFormed(zero)); - - // Invalid file descriptors - Fd bad(-1); - Fd weird(-9); - EXPECT_FALSE(isWellFormed(bad)); - EXPECT_FALSE(isWellFormed(weird)); - - // Default constructor - EXPECT_EQ(Fd(-1), Fd()); - std::stringstream ss; - ss << fd3 << " " << fd6 << " " << bad << " " << weird; - EXPECT_EQ("Fd[1] Fd[8] Fd[-1] Fd[-9]", ss.str()); -} - -class UniqueFdTest : public testing::Test { - protected: - StrictMock<ScopedMockSyscalls> mSyscalls; -}; - -TEST_F(UniqueFdTest, operatorOstream) { - UniqueFd u(97); - EXPECT_CALL(mSyscalls, close(toFd(u))).WillOnce(Return(status::ok)); - std::stringstream ss; - ss << u; - EXPECT_EQ("UniqueFd[Fd[97]]", ss.str()); - u.reset(); -} - -TEST_F(UniqueFdTest, destructor) { - { - UniqueFd u(98); - EXPECT_CALL(mSyscalls, close(toFd(u))).WillOnce(Return(status::ok)); - } - // Expectation above should be upon leaving nested scope - Mock::VerifyAndClearExpectations(&mSyscalls); -} - -TEST_F(UniqueFdTest, reset) { - UniqueFd u(99); - EXPECT_CALL(mSyscalls, close(toFd(u))).WillOnce(Return(status::ok)); - u.reset(); - - // Expectation above should be upon reset - Mock::VerifyAndClearExpectations(&mSyscalls); -} - -TEST_F(UniqueFdTest, moveConstructor) { - constexpr Fd kFd(101); - UniqueFd u1(kFd); - { - UniqueFd u2(std::move(u1)); - // NOLINTNEXTLINE bugprone-use-after-move - EXPECT_FALSE(isWellFormed(u1)); - EXPECT_TRUE(isWellFormed(u2)); - EXPECT_CALL(mSyscalls, close(kFd)).WillOnce(Return(status::ok)); - } - // Expectation above should be upon leaving nested scope - Mock::VerifyAndClearExpectations(&mSyscalls); -} - -TEST_F(UniqueFdTest, moveAssignment) { - constexpr Fd kFd(102); - UniqueFd u1(kFd); - { - UniqueFd u2 = std::move(u1); - // NOLINTNEXTLINE bugprone-use-after-move - EXPECT_FALSE(isWellFormed(u1)); - EXPECT_TRUE(isWellFormed(u2)); - UniqueFd u3; - u3 = std::move(u2); - // NOLINTNEXTLINE bugprone-use-after-move - EXPECT_FALSE(isWellFormed(u2)); - EXPECT_TRUE(isWellFormed(u3)); - EXPECT_CALL(mSyscalls, close(kFd)).WillOnce(Return(status::ok)); - } - // Expectation above should be upon leaving nested scope - Mock::VerifyAndClearExpectations(&mSyscalls); -} - -TEST_F(UniqueFdTest, constConstructor) { - constexpr Fd kFd(103); - const UniqueFd u(kFd); - EXPECT_CALL(mSyscalls, close(toFd(u))).WillOnce(Return(status::ok)); -} - -TEST_F(UniqueFdTest, closeFailure) { - constexpr Fd kFd(103); - UniqueFd u(kFd); - EXPECT_CALL(mSyscalls, close(toFd(u))).WillOnce(Return(statusFromErrno(EINTR, "test"))); - EXPECT_DEBUG_DEATH(u.reset(), ""); -} - -} // namespace netdutils -} // namespace android diff --git a/libnetdutils/InternetAddresses.cpp b/libnetdutils/InternetAddresses.cpp deleted file mode 100644 index 322f1b1d..00000000 --- a/libnetdutils/InternetAddresses.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "netdutils/InternetAddresses.h" - -#include <string> - -#include <android-base/stringprintf.h> -#include <arpa/inet.h> -#include <netdb.h> -#include <sys/socket.h> -#include <sys/types.h> - -namespace android { - -using base::StringPrintf; - -namespace netdutils { - -std::string IPAddress::toString() const noexcept { - char repr[INET6_ADDRSTRLEN] = "\0"; - - switch (mData.family) { - case AF_UNSPEC: - return "<unspecified>"; - case AF_INET: { - const in_addr v4 = mData.ip.v4; - inet_ntop(AF_INET, &v4, repr, sizeof(repr)); - break; - } - case AF_INET6: { - const in6_addr v6 = mData.ip.v6; - inet_ntop(AF_INET6, &v6, repr, sizeof(repr)); - break; - } - default: - return "<unknown_family>"; - } - - if (mData.family == AF_INET6 && mData.scope_id > 0) { - return StringPrintf("%s%%%u", repr, mData.scope_id); - } - - return repr; -} - -bool IPAddress::forString(const std::string& repr, IPAddress* ip) { - const addrinfo hints = { - .ai_flags = AI_NUMERICHOST | AI_NUMERICSERV, - }; - addrinfo* res; - const int ret = getaddrinfo(repr.c_str(), nullptr, &hints, &res); - ScopedAddrinfo res_cleanup(res); - if (ret != 0) { - return false; - } - - bool rval = true; - switch (res[0].ai_family) { - case AF_INET: { - sockaddr_in* sin = (sockaddr_in*) res[0].ai_addr; - if (ip) *ip = IPAddress(sin->sin_addr); - break; - } - case AF_INET6: { - sockaddr_in6* sin6 = (sockaddr_in6*) res[0].ai_addr; - if (ip) *ip = IPAddress(sin6->sin6_addr, sin6->sin6_scope_id); - break; - } - default: - rval = false; - break; - } - - return rval; -} - -IPPrefix::IPPrefix(const IPAddress& ip, int length) : IPPrefix(ip) { - // Silently treat CIDR lengths like "-1" as meaning the full bit length - // appropriate to the address family. - if (length < 0) return; - if (length >= mData.cidrlen) return; - - switch (mData.family) { - case AF_UNSPEC: - break; - case AF_INET: { - const in_addr_t mask = (length > 0) ? (~0U) << (IPV4_ADDR_BITS - length) : 0U; - mData.ip.v4.s_addr &= htonl(mask); - mData.cidrlen = static_cast<uint8_t>(length); - break; - } - case AF_INET6: { - // The byte in which this CIDR length falls. - const int which = length / 8; - const int mask = (length % 8 == 0) ? 0 : 0xff << (8 - length % 8); - mData.ip.v6.s6_addr[which] &= mask; - for (int i = which + 1; i < IPV6_ADDR_LEN; i++) { - mData.ip.v6.s6_addr[i] = 0U; - } - mData.cidrlen = static_cast<uint8_t>(length); - break; - } - default: - // TODO: Complain bitterly about possible data corruption? - return; - } -} - -bool IPPrefix::isUninitialized() const noexcept { - static const internal_::compact_ipdata empty{}; - return mData == empty; -} - -bool IPPrefix::forString(const std::string& repr, IPPrefix* prefix) { - size_t index = repr.find('/'); - if (index == std::string::npos) return false; - - // Parse the IP address. - IPAddress ip; - if (!IPAddress::forString(repr.substr(0, index), &ip)) return false; - - // Parse the prefix length. Can't use base::ParseUint because it accepts non-base 10 input. - const char* prefixString = repr.c_str() + index + 1; - if (!isdigit(*prefixString)) return false; - char* endptr; - unsigned long prefixlen = strtoul(prefixString, &endptr, 10); - if (*endptr != '\0') return false; - - uint8_t maxlen = (ip.family() == AF_INET) ? 32 : 128; - if (prefixlen > maxlen) return false; - - *prefix = IPPrefix(ip, prefixlen); - return true; -} - -std::string IPPrefix::toString() const noexcept { - return StringPrintf("%s/%d", ip().toString().c_str(), mData.cidrlen); -} - -std::string IPSockAddr::toString() const noexcept { - switch (mData.family) { - case AF_INET6: - return StringPrintf("[%s]:%u", ip().toString().c_str(), mData.port); - default: - return StringPrintf("%s:%u", ip().toString().c_str(), mData.port); - } -} - -} // namespace netdutils -} // namespace android diff --git a/libnetdutils/InternetAddressesTest.cpp b/libnetdutils/InternetAddressesTest.cpp deleted file mode 100644 index f75fa769..00000000 --- a/libnetdutils/InternetAddressesTest.cpp +++ /dev/null @@ -1,541 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <cstdint> -#include <limits> -#include <sstream> -#include <string> -#include <vector> - -#include <android-base/macros.h> -#include <gtest/gtest.h> - -#include "netdutils/InternetAddresses.h" - -namespace android { -namespace netdutils { -namespace { - -enum Relation { EQ, LT }; - -std::ostream& operator<<(std::ostream& os, Relation relation) { - switch (relation) { - case EQ: os << "eq"; break; - case LT: os << "lt"; break; - default: os << "?!"; break; - } - return os; -} - -template <typename T> -struct OperatorExpectation { - const Relation relation; - const T obj1; - const T obj2; - - std::string toString() const { - std::stringstream output; - output << obj1 << " " << relation << " " << obj2; - return output.str(); - } -}; - -template <typename T> -void testGamutOfOperators(const OperatorExpectation<T>& expectation) { - switch (expectation.relation) { - case EQ: - EXPECT_TRUE(expectation.obj1 == expectation.obj2); - EXPECT_TRUE(expectation.obj1 <= expectation.obj2); - EXPECT_TRUE(expectation.obj1 >= expectation.obj2); - EXPECT_FALSE(expectation.obj1 != expectation.obj2); - EXPECT_FALSE(expectation.obj1 < expectation.obj2); - EXPECT_FALSE(expectation.obj1 > expectation.obj2); - break; - - case LT: - EXPECT_TRUE(expectation.obj1 < expectation.obj2); - EXPECT_TRUE(expectation.obj1 <= expectation.obj2); - EXPECT_TRUE(expectation.obj1 != expectation.obj2); - EXPECT_FALSE(expectation.obj1 > expectation.obj2); - EXPECT_FALSE(expectation.obj1 >= expectation.obj2); - EXPECT_FALSE(expectation.obj1 == expectation.obj2); - break; - - default: - FAIL() << "Unknown relation given in test expectation"; - } -} - -const in_addr IPV4_ANY{htonl(INADDR_ANY)}; -const in_addr IPV4_LOOPBACK{htonl(INADDR_LOOPBACK)}; -const in_addr IPV4_ONES{~0U}; -const in6_addr IPV6_ANY = IN6ADDR_ANY_INIT; -const in6_addr IPV6_LOOPBACK = IN6ADDR_LOOPBACK_INIT; -const in6_addr FE80{{{0xfe,0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}; -const in6_addr FE80_1{{{0xfe,0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,1}}}; -const in6_addr FE80_2{{{0xfe,0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,2}}}; -const uint8_t ff = std::numeric_limits<uint8_t>::max(); -const in6_addr IPV6_ONES{{{ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff}}}; - -TEST(IPAddressTest, GamutOfOperators) { - const std::vector<OperatorExpectation<IPAddress>> kExpectations{ - {EQ, IPAddress(), IPAddress()}, - {EQ, IPAddress(IPV4_ONES), IPAddress(IPV4_ONES)}, - {EQ, IPAddress(IPV6_ONES), IPAddress(IPV6_ONES)}, - {EQ, IPAddress(FE80_1), IPAddress(FE80_1)}, - {EQ, IPAddress(FE80_2), IPAddress(FE80_2)}, - {LT, IPAddress(), IPAddress(IPV4_ANY)}, - {LT, IPAddress(), IPAddress(IPV4_ONES)}, - {LT, IPAddress(), IPAddress(IPV6_ANY)}, - {LT, IPAddress(), IPAddress(IPV6_ONES)}, - {LT, IPAddress(IPV4_ANY), IPAddress(IPV4_ONES)}, - {LT, IPAddress(IPV4_ANY), IPAddress(IPV6_ANY)}, - {LT, IPAddress(IPV4_ONES), IPAddress(IPV6_ANY)}, - {LT, IPAddress(IPV4_ONES), IPAddress(IPV6_ONES)}, - {LT, IPAddress(IPV6_ANY), IPAddress(IPV6_LOOPBACK)}, - {LT, IPAddress(IPV6_ANY), IPAddress(IPV6_ONES)}, - {LT, IPAddress(IPV6_LOOPBACK), IPAddress(IPV6_ONES)}, - {LT, IPAddress(FE80_1), IPAddress(FE80_2)}, - {LT, IPAddress(FE80_1), IPAddress(IPV6_ONES)}, - {LT, IPAddress(FE80_2), IPAddress(IPV6_ONES)}, - // Sort by scoped_id within the same address. - {LT, IPAddress(FE80_1), IPAddress(FE80_1, 1)}, - {LT, IPAddress(FE80_1, 1), IPAddress(FE80_1, 2)}, - // Sort by address first, scope_id second. - {LT, IPAddress(FE80_1, 2), IPAddress(FE80_2, 1)}, - }; - - size_t tests_run = 0; - for (const auto& expectation : kExpectations) { - SCOPED_TRACE(expectation.toString()); - EXPECT_NO_FATAL_FAILURE(testGamutOfOperators(expectation)); - tests_run++; - } - EXPECT_EQ(kExpectations.size(), tests_run); -} - -TEST(IPAddressTest, ScopeIds) { - // Scope IDs ignored for IPv4 addresses. - const IPAddress ones(IPV4_ONES); - EXPECT_EQ(0U, ones.scope_id()); - const IPAddress ones22(ones, 22); - EXPECT_EQ(0U, ones22.scope_id()); - EXPECT_EQ(ones, ones22); - const IPAddress ones23(ones, 23); - EXPECT_EQ(0U, ones23.scope_id()); - EXPECT_EQ(ones22, ones23); - - EXPECT_EQ("fe80::1%22", IPAddress(FE80_1, 22).toString()); - EXPECT_EQ("fe80::2%23", IPAddress(FE80_2, 23).toString()); - - // Verify that given an IPAddress with a scope_id an address without a - // scope_id can be constructed (just in case it's useful). - const IPAddress fe80_intf22(FE80_1, 22); - EXPECT_EQ(22U, fe80_intf22.scope_id()); - EXPECT_EQ(fe80_intf22, IPAddress(fe80_intf22)); - EXPECT_EQ(IPAddress(FE80_1), IPAddress(fe80_intf22, 0)); -} - -TEST(IPAddressTest, forString) { - IPAddress ip; - - EXPECT_FALSE(IPAddress::forString("not_an_ip", &ip)); - EXPECT_FALSE(IPAddress::forString("not_an_ip", nullptr)); - EXPECT_EQ(IPAddress(), IPAddress::forString("not_an_ip")); - - EXPECT_EQ(IPAddress(IPV4_ANY), IPAddress::forString("0.0.0.0")); - EXPECT_EQ(IPAddress(IPV4_ONES), IPAddress::forString("255.255.255.255")); - EXPECT_EQ(IPAddress(IPV4_LOOPBACK), IPAddress::forString("127.0.0.1")); - - EXPECT_EQ(IPAddress(IPV6_ANY), IPAddress::forString("::")); - EXPECT_EQ(IPAddress(IPV6_ANY), IPAddress::forString("::0")); - EXPECT_EQ(IPAddress(IPV6_ANY), IPAddress::forString("0::")); - EXPECT_EQ(IPAddress(IPV6_LOOPBACK), IPAddress::forString("::1")); - EXPECT_EQ(IPAddress(IPV6_LOOPBACK), IPAddress::forString("0::1")); - EXPECT_EQ(IPAddress(FE80_1), IPAddress::forString("fe80::1")); - EXPECT_EQ(IPAddress(FE80_1, 22), IPAddress::forString("fe80::1%22")); - // This relies upon having a loopback interface named "lo" with ifindex 1. - EXPECT_EQ(IPAddress(FE80_1, 1), IPAddress::forString("fe80::1%lo")); -} - -TEST(IPPrefixTest, forString) { - IPPrefix prefix; - - EXPECT_FALSE(IPPrefix::forString("", &prefix)); - EXPECT_FALSE(IPPrefix::forString("invalid", &prefix)); - EXPECT_FALSE(IPPrefix::forString("192.0.2.0", &prefix)); - EXPECT_FALSE(IPPrefix::forString("2001::db8::", &prefix)); - - EXPECT_FALSE(IPPrefix::forString("2001:db8::/", &prefix)); - EXPECT_FALSE(IPPrefix::forString("2001:db8:://32", &prefix)); - EXPECT_FALSE(IPPrefix::forString("2001:db8::/32z", &prefix)); - EXPECT_FALSE(IPPrefix::forString("2001:db8::/32/", &prefix)); - EXPECT_FALSE(IPPrefix::forString("2001:db8::/0x20", &prefix)); - EXPECT_FALSE(IPPrefix::forString("2001:db8:: /32", &prefix)); - EXPECT_FALSE(IPPrefix::forString("2001:db8::/ 32", &prefix)); - EXPECT_FALSE(IPPrefix::forString(" 2001:db8::/32", &prefix)); - EXPECT_FALSE(IPPrefix::forString("2001:db8::/32 ", &prefix)); - EXPECT_FALSE(IPPrefix::forString("2001:db8::/+32", &prefix)); - - EXPECT_FALSE(IPPrefix::forString("192.0.2.0/33", &prefix)); - EXPECT_FALSE(IPPrefix::forString("2001:db8::/129", &prefix)); - EXPECT_FALSE(IPPrefix::forString("192.0.2.0/-1", &prefix)); - EXPECT_FALSE(IPPrefix::forString("2001:db8::/-1", &prefix)); - - EXPECT_TRUE(IPPrefix::forString("2001:db8::/32", &prefix)); - EXPECT_EQ("2001:db8::/32", prefix.toString()); - EXPECT_EQ(IPPrefix(IPAddress::forString("2001:db8::"), 32), prefix); - - EXPECT_EQ(IPPrefix(), IPPrefix::forString("invalid")); - - EXPECT_EQ("0.0.0.0/0", IPPrefix::forString("0.0.0.0/0").toString()); - EXPECT_EQ("::/0", IPPrefix::forString("::/0").toString()); - EXPECT_EQ("192.0.2.128/25", IPPrefix::forString("192.0.2.131/25").toString()); - EXPECT_EQ("2001:db8:1:2:3:4:5:4/126", - IPPrefix::forString("2001:db8:1:2:3:4:5:6/126").toString()); -} - -TEST(IPPrefixTest, IPv4Truncation) { - const auto prefixStr = [](int length) -> std::string { - return IPPrefix(IPAddress(IPV4_ONES), length).toString(); - }; - - EXPECT_EQ("0.0.0.0/0", prefixStr(0)); - - EXPECT_EQ("128.0.0.0/1", prefixStr(1)); - EXPECT_EQ("192.0.0.0/2", prefixStr(2)); - EXPECT_EQ("224.0.0.0/3", prefixStr(3)); - EXPECT_EQ("240.0.0.0/4", prefixStr(4)); - EXPECT_EQ("248.0.0.0/5", prefixStr(5)); - EXPECT_EQ("252.0.0.0/6", prefixStr(6)); - EXPECT_EQ("254.0.0.0/7", prefixStr(7)); - EXPECT_EQ("255.0.0.0/8", prefixStr(8)); - - EXPECT_EQ("255.128.0.0/9", prefixStr(9)); - EXPECT_EQ("255.192.0.0/10", prefixStr(10)); - EXPECT_EQ("255.224.0.0/11", prefixStr(11)); - EXPECT_EQ("255.240.0.0/12", prefixStr(12)); - EXPECT_EQ("255.248.0.0/13", prefixStr(13)); - EXPECT_EQ("255.252.0.0/14", prefixStr(14)); - EXPECT_EQ("255.254.0.0/15", prefixStr(15)); - EXPECT_EQ("255.255.0.0/16", prefixStr(16)); - - EXPECT_EQ("255.255.128.0/17", prefixStr(17)); - EXPECT_EQ("255.255.192.0/18", prefixStr(18)); - EXPECT_EQ("255.255.224.0/19", prefixStr(19)); - EXPECT_EQ("255.255.240.0/20", prefixStr(20)); - EXPECT_EQ("255.255.248.0/21", prefixStr(21)); - EXPECT_EQ("255.255.252.0/22", prefixStr(22)); - EXPECT_EQ("255.255.254.0/23", prefixStr(23)); - EXPECT_EQ("255.255.255.0/24", prefixStr(24)); - - EXPECT_EQ("255.255.255.128/25", prefixStr(25)); - EXPECT_EQ("255.255.255.192/26", prefixStr(26)); - EXPECT_EQ("255.255.255.224/27", prefixStr(27)); - EXPECT_EQ("255.255.255.240/28", prefixStr(28)); - EXPECT_EQ("255.255.255.248/29", prefixStr(29)); - EXPECT_EQ("255.255.255.252/30", prefixStr(30)); - EXPECT_EQ("255.255.255.254/31", prefixStr(31)); - EXPECT_EQ("255.255.255.255/32", prefixStr(32)); -} - -TEST(IPPrefixTest, IPv6Truncation) { - const auto prefixStr = [](int length) -> std::string { - return IPPrefix(IPAddress(IPV6_ONES), length).toString(); - }; - - EXPECT_EQ("::/0", prefixStr(0)); - - EXPECT_EQ("8000::/1", prefixStr(1)); - EXPECT_EQ("c000::/2", prefixStr(2)); - EXPECT_EQ("e000::/3", prefixStr(3)); - EXPECT_EQ("f000::/4", prefixStr(4)); - EXPECT_EQ("f800::/5", prefixStr(5)); - EXPECT_EQ("fc00::/6", prefixStr(6)); - EXPECT_EQ("fe00::/7", prefixStr(7)); - EXPECT_EQ("ff00::/8", prefixStr(8)); - - EXPECT_EQ("ff80::/9", prefixStr(9)); - EXPECT_EQ("ffc0::/10", prefixStr(10)); - EXPECT_EQ("ffe0::/11", prefixStr(11)); - EXPECT_EQ("fff0::/12", prefixStr(12)); - EXPECT_EQ("fff8::/13", prefixStr(13)); - EXPECT_EQ("fffc::/14", prefixStr(14)); - EXPECT_EQ("fffe::/15", prefixStr(15)); - EXPECT_EQ("ffff::/16", prefixStr(16)); - - EXPECT_EQ("ffff:8000::/17", prefixStr(17)); - EXPECT_EQ("ffff:c000::/18", prefixStr(18)); - EXPECT_EQ("ffff:e000::/19", prefixStr(19)); - EXPECT_EQ("ffff:f000::/20", prefixStr(20)); - EXPECT_EQ("ffff:f800::/21", prefixStr(21)); - EXPECT_EQ("ffff:fc00::/22", prefixStr(22)); - EXPECT_EQ("ffff:fe00::/23", prefixStr(23)); - EXPECT_EQ("ffff:ff00::/24", prefixStr(24)); - - EXPECT_EQ("ffff:ff80::/25", prefixStr(25)); - EXPECT_EQ("ffff:ffc0::/26", prefixStr(26)); - EXPECT_EQ("ffff:ffe0::/27", prefixStr(27)); - EXPECT_EQ("ffff:fff0::/28", prefixStr(28)); - EXPECT_EQ("ffff:fff8::/29", prefixStr(29)); - EXPECT_EQ("ffff:fffc::/30", prefixStr(30)); - EXPECT_EQ("ffff:fffe::/31", prefixStr(31)); - EXPECT_EQ("ffff:ffff::/32", prefixStr(32)); - - EXPECT_EQ("ffff:ffff:8000::/33", prefixStr(33)); - EXPECT_EQ("ffff:ffff:c000::/34", prefixStr(34)); - EXPECT_EQ("ffff:ffff:e000::/35", prefixStr(35)); - EXPECT_EQ("ffff:ffff:f000::/36", prefixStr(36)); - EXPECT_EQ("ffff:ffff:f800::/37", prefixStr(37)); - EXPECT_EQ("ffff:ffff:fc00::/38", prefixStr(38)); - EXPECT_EQ("ffff:ffff:fe00::/39", prefixStr(39)); - EXPECT_EQ("ffff:ffff:ff00::/40", prefixStr(40)); - - EXPECT_EQ("ffff:ffff:ff80::/41", prefixStr(41)); - EXPECT_EQ("ffff:ffff:ffc0::/42", prefixStr(42)); - EXPECT_EQ("ffff:ffff:ffe0::/43", prefixStr(43)); - EXPECT_EQ("ffff:ffff:fff0::/44", prefixStr(44)); - EXPECT_EQ("ffff:ffff:fff8::/45", prefixStr(45)); - EXPECT_EQ("ffff:ffff:fffc::/46", prefixStr(46)); - EXPECT_EQ("ffff:ffff:fffe::/47", prefixStr(47)); - EXPECT_EQ("ffff:ffff:ffff::/48", prefixStr(48)); - - EXPECT_EQ("ffff:ffff:ffff:8000::/49", prefixStr(49)); - EXPECT_EQ("ffff:ffff:ffff:c000::/50", prefixStr(50)); - EXPECT_EQ("ffff:ffff:ffff:e000::/51", prefixStr(51)); - EXPECT_EQ("ffff:ffff:ffff:f000::/52", prefixStr(52)); - EXPECT_EQ("ffff:ffff:ffff:f800::/53", prefixStr(53)); - EXPECT_EQ("ffff:ffff:ffff:fc00::/54", prefixStr(54)); - EXPECT_EQ("ffff:ffff:ffff:fe00::/55", prefixStr(55)); - EXPECT_EQ("ffff:ffff:ffff:ff00::/56", prefixStr(56)); - - EXPECT_EQ("ffff:ffff:ffff:ff80::/57", prefixStr(57)); - EXPECT_EQ("ffff:ffff:ffff:ffc0::/58", prefixStr(58)); - EXPECT_EQ("ffff:ffff:ffff:ffe0::/59", prefixStr(59)); - EXPECT_EQ("ffff:ffff:ffff:fff0::/60", prefixStr(60)); - EXPECT_EQ("ffff:ffff:ffff:fff8::/61", prefixStr(61)); - EXPECT_EQ("ffff:ffff:ffff:fffc::/62", prefixStr(62)); - EXPECT_EQ("ffff:ffff:ffff:fffe::/63", prefixStr(63)); - EXPECT_EQ("ffff:ffff:ffff:ffff::/64", prefixStr(64)); - - EXPECT_EQ("ffff:ffff:ffff:ffff:8000::/65", prefixStr(65)); - EXPECT_EQ("ffff:ffff:ffff:ffff:c000::/66", prefixStr(66)); - EXPECT_EQ("ffff:ffff:ffff:ffff:e000::/67", prefixStr(67)); - EXPECT_EQ("ffff:ffff:ffff:ffff:f000::/68", prefixStr(68)); - EXPECT_EQ("ffff:ffff:ffff:ffff:f800::/69", prefixStr(69)); - EXPECT_EQ("ffff:ffff:ffff:ffff:fc00::/70", prefixStr(70)); - EXPECT_EQ("ffff:ffff:ffff:ffff:fe00::/71", prefixStr(71)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ff00::/72", prefixStr(72)); - - EXPECT_EQ("ffff:ffff:ffff:ffff:ff80::/73", prefixStr(73)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffc0::/74", prefixStr(74)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffe0::/75", prefixStr(75)); - EXPECT_EQ("ffff:ffff:ffff:ffff:fff0::/76", prefixStr(76)); - EXPECT_EQ("ffff:ffff:ffff:ffff:fff8::/77", prefixStr(77)); - EXPECT_EQ("ffff:ffff:ffff:ffff:fffc::/78", prefixStr(78)); - EXPECT_EQ("ffff:ffff:ffff:ffff:fffe::/79", prefixStr(79)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff::/80", prefixStr(80)); - - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:8000::/81", prefixStr(81)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:c000::/82", prefixStr(82)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:e000::/83", prefixStr(83)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:f000::/84", prefixStr(84)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:f800::/85", prefixStr(85)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:fc00::/86", prefixStr(86)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:fe00::/87", prefixStr(87)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ff00::/88", prefixStr(88)); - - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ff80::/89", prefixStr(89)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffc0::/90", prefixStr(90)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffe0::/91", prefixStr(91)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:fff0::/92", prefixStr(92)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:fff8::/93", prefixStr(93)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:fffc::/94", prefixStr(94)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:fffe::/95", prefixStr(95)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff::/96", prefixStr(96)); - - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:8000:0/97", prefixStr(97)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:c000:0/98", prefixStr(98)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:e000:0/99", prefixStr(99)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:f000:0/100", prefixStr(100)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:f800:0/101", prefixStr(101)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:fc00:0/102", prefixStr(102)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:fe00:0/103", prefixStr(103)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ff00:0/104", prefixStr(104)); - - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ff80:0/105", prefixStr(105)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffc0:0/106", prefixStr(106)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffe0:0/107", prefixStr(107)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:fff0:0/108", prefixStr(108)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:fff8:0/109", prefixStr(109)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:fffc:0/110", prefixStr(110)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:fffe:0/111", prefixStr(111)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:0/112", prefixStr(112)); - - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:8000/113", prefixStr(113)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:c000/114", prefixStr(114)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:e000/115", prefixStr(115)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:f000/116", prefixStr(116)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:f800/117", prefixStr(117)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fc00/118", prefixStr(118)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fe00/119", prefixStr(119)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00/120", prefixStr(120)); - - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff80/121", prefixStr(121)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffc0/122", prefixStr(122)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffe0/123", prefixStr(123)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff0/124", prefixStr(124)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff8/125", prefixStr(125)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffc/126", prefixStr(126)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe/127", prefixStr(127)); - EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128", prefixStr(128)); -} - -TEST(IPPrefixTest, TruncationOther) { - const struct { - const char* ip; - const int cidrLen; - const char* ipTruncated; - } testExpectations[] = { - {"192.0.2.0", 24, "192.0.2.0"}, - {"192.0.2.0", 23, "192.0.2.0"}, - {"192.0.2.0", 22, "192.0.0.0"}, - {"192.0.2.0", 1, "128.0.0.0"}, - {"2001:db8:cafe:d00d::", 56, "2001:db8:cafe:d000::"}, - {"2001:db8:cafe:d00d::", 48, "2001:db8:cafe::"}, - {"2001:db8:cafe:d00d::", 47, "2001:db8:cafe::"}, - {"2001:db8:cafe:d00d::", 46, "2001:db8:cafc::"}, - }; - - for (const auto& expectation : testExpectations) { - IPAddress ip; - EXPECT_TRUE(IPAddress::forString(expectation.ip, &ip)) - << "Failed to parse IP address " << expectation.ip; - - IPAddress ipTruncated; - EXPECT_TRUE(IPAddress::forString(expectation.ipTruncated, &ipTruncated)) - << "Failed to parse IP address " << expectation.ipTruncated; - - IPPrefix prefix(ip, expectation.cidrLen); - - EXPECT_EQ(expectation.cidrLen, prefix.length()) - << "Unexpected cidrLen " << expectation.cidrLen; - EXPECT_EQ(ipTruncated, prefix.ip()) - << "Unexpected IP truncation: " << prefix.ip() << ", expected: " << ipTruncated; - } -} - -TEST(IPPrefixTest, GamutOfOperators) { - const std::vector<OperatorExpectation<IPPrefix>> kExpectations{ - {EQ, IPPrefix(), IPPrefix()}, - {EQ, IPPrefix(IPAddress(IPV4_ANY), 0), IPPrefix(IPAddress(IPV4_ANY), 0)}, - {EQ, IPPrefix(IPAddress(IPV4_ANY), IPV4_ADDR_BITS), IPPrefix(IPAddress(IPV4_ANY))}, - {EQ, IPPrefix(IPAddress(IPV6_ANY), 0), IPPrefix(IPAddress(IPV6_ANY), 0)}, - {EQ, IPPrefix(IPAddress(IPV6_ANY), IPV6_ADDR_BITS), IPPrefix(IPAddress(IPV6_ANY))}, - // Needlessly fully-specified IPv6 link-local address. - {EQ, IPPrefix(IPAddress(FE80_1)), IPPrefix(IPAddress(FE80_1, 0), IPV6_ADDR_BITS)}, - // Different IPv6 link-local addresses within the same /64, no scoped_id: same /64. - {EQ, IPPrefix(IPAddress(FE80_1), 64), IPPrefix(IPAddress(FE80_2), 64)}, - // Different IPv6 link-local address within the same /64, same scoped_id: same /64. - {EQ, IPPrefix(IPAddress(FE80_1, 17), 64), IPPrefix(IPAddress(FE80_2, 17), 64)}, - // Unspecified < IPv4. - {LT, IPPrefix(), IPPrefix(IPAddress(IPV4_ANY), 0)}, - // Same IPv4 base address sorts by prefix length. - {LT, IPPrefix(IPAddress(IPV4_ANY), 0), IPPrefix(IPAddress(IPV4_ANY), 1)}, - {LT, IPPrefix(IPAddress(IPV4_ANY), 1), IPPrefix(IPAddress(IPV4_ANY), IPV4_ADDR_BITS)}, - // Truncation means each base IPv4 address is different. - {LT, IPPrefix(IPAddress(IPV4_ONES), 0), IPPrefix(IPAddress(IPV4_ONES), 1)}, - {LT, IPPrefix(IPAddress(IPV4_ONES), 1), IPPrefix(IPAddress(IPV4_ONES), IPV4_ADDR_BITS)}, - // Sort by base IPv4 addresses first. - {LT, IPPrefix(IPAddress(IPV4_ANY), 0), IPPrefix(IPAddress::forString("0.0.0.1"))}, - {LT, IPPrefix(IPAddress(IPV4_ANY), 1), IPPrefix(IPAddress::forString("0.0.0.1"))}, - {LT, IPPrefix(IPAddress(IPV4_ANY), 24), IPPrefix(IPAddress::forString("0.0.0.1"))}, - // IPv4 < IPv6. - {LT, IPPrefix(IPAddress(IPV4_ANY), 0), IPPrefix(IPAddress(IPV6_ANY), 0)}, - {LT, IPPrefix(IPAddress(IPV4_ONES)), IPPrefix(IPAddress(IPV6_ANY))}, - // Unspecified < IPv6. - {LT, IPPrefix(), IPPrefix(IPAddress(IPV6_ANY), 0)}, - // Same IPv6 base address sorts by prefix length. - {LT, IPPrefix(IPAddress(IPV6_ANY), 0), IPPrefix(IPAddress(IPV6_ANY), 1)}, - {LT, IPPrefix(IPAddress(IPV6_ANY), 1), IPPrefix(IPAddress(IPV6_ANY), IPV6_ADDR_BITS)}, - // Truncation means each base IPv6 address is different. - {LT, IPPrefix(IPAddress(IPV6_ONES), 0), IPPrefix(IPAddress(IPV6_ONES), 1)}, - {LT, IPPrefix(IPAddress(IPV6_ONES), 1), IPPrefix(IPAddress(IPV6_ONES), IPV6_ADDR_BITS)}, - // Different IPv6 link-local address in same /64, different scoped_id: different /64. - {LT, IPPrefix(IPAddress(FE80_1, 17), 64), IPPrefix(IPAddress(FE80_2, 22), 64)}, - {LT, IPPrefix(IPAddress(FE80_1, 17), 64), IPPrefix(IPAddress(FE80_1, 18), 64)}, - {LT, IPPrefix(IPAddress(FE80_1, 18), 64), IPPrefix(IPAddress(FE80_1, 19), 64)}, - }; - - size_t tests_run = 0; - for (const auto& expectation : kExpectations) { - SCOPED_TRACE(expectation.toString()); - EXPECT_NO_FATAL_FAILURE(testGamutOfOperators(expectation)); - tests_run++; - } - EXPECT_EQ(kExpectations.size(), tests_run); -} - -TEST(IPSockAddrTest, GamutOfOperators) { - const std::vector<OperatorExpectation<IPSockAddr>> kExpectations{ - {EQ, IPSockAddr(), IPSockAddr()}, - {EQ, IPSockAddr(IPAddress(IPV4_ANY)), IPSockAddr(IPAddress(IPV4_ANY), 0)}, - {EQ, IPSockAddr(IPAddress(IPV6_ANY)), IPSockAddr(IPAddress(IPV6_ANY), 0)}, - {EQ, IPSockAddr(IPAddress(FE80_1), 80), IPSockAddr(IPAddress(FE80_1), 80)}, - {EQ, IPSockAddr(IPAddress(FE80_1, 17)), IPSockAddr(IPAddress(FE80_1, 17), 0)}, - {LT, IPSockAddr(IPAddress(IPV4_ANY), 0), IPSockAddr(IPAddress(IPV4_ANY), 1)}, - {LT, IPSockAddr(IPAddress(IPV4_ANY), 53), IPSockAddr(IPAddress(IPV4_ANY), 123)}, - {LT, IPSockAddr(IPAddress(IPV4_ONES), 123), IPSockAddr(IPAddress(IPV6_ANY), 53)}, - {LT, IPSockAddr(IPAddress(IPV6_ANY), 0), IPSockAddr(IPAddress(IPV6_ANY), 1)}, - {LT, IPSockAddr(IPAddress(IPV6_ANY), 53), IPSockAddr(IPAddress(IPV6_ANY), 123)}, - {LT, IPSockAddr(IPAddress(FE80_1), 80), IPSockAddr(IPAddress(FE80_1, 17), 80)}, - {LT, IPSockAddr(IPAddress(FE80_1, 17), 80), IPSockAddr(IPAddress(FE80_1, 22), 80)}, - }; - - size_t tests_run = 0; - for (const auto& expectation : kExpectations) { - SCOPED_TRACE(expectation.toString()); - EXPECT_NO_FATAL_FAILURE(testGamutOfOperators(expectation)); - tests_run++; - } - EXPECT_EQ(kExpectations.size(), tests_run); -} - -TEST(IPSockAddrTest, toString) { - EXPECT_EQ("<unspecified>:0", IPSockAddr().toString()); - EXPECT_EQ("0.0.0.0:0", IPSockAddr(IPAddress(IPV4_ANY)).toString()); - EXPECT_EQ("255.255.255.255:67", IPSockAddr(IPAddress(IPV4_ONES), 67).toString()); - EXPECT_EQ("[::]:0", IPSockAddr(IPAddress(IPV6_ANY)).toString()); - EXPECT_EQ("[::1]:53", IPSockAddr(IPAddress(IPV6_LOOPBACK), 53).toString()); - EXPECT_EQ("[fe80::1]:0", IPSockAddr(IPAddress(FE80_1)).toString()); - EXPECT_EQ("[fe80::2%17]:123", IPSockAddr(IPAddress(FE80_2, 17), 123).toString()); -} - -TEST(CompatIPDataTest, ConversionsClearUnneededValues) { - const uint32_t idx = 17; - const IPSockAddr linkLocalNtpSockaddr(IPAddress(FE80_2, idx), 123); - EXPECT_EQ(IPAddress(FE80_2, idx), linkLocalNtpSockaddr.ip()); - // IPSockAddr(IPSockaddr.ip()) see the port cleared. - EXPECT_EQ(0, IPSockAddr(linkLocalNtpSockaddr.ip()).port()); - const IPPrefix linkLocalPrefix(linkLocalNtpSockaddr.ip(), 64); - EXPECT_EQ(IPAddress(FE80, idx), linkLocalPrefix.ip()); - // IPPrefix(IPPrefix.ip()) see the CIDR length cleared. - EXPECT_EQ(IPV6_ADDR_BITS, IPPrefix(linkLocalPrefix.ip()).length()); -} - -} // namespace -} // namespace netdutils -} // namespace android diff --git a/libnetdutils/Log.cpp b/libnetdutils/Log.cpp deleted file mode 100644 index d2ce98f0..00000000 --- a/libnetdutils/Log.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "netdutils/Log.h" -#include "netdutils/Slice.h" - -#include <chrono> -#include <ctime> -#include <iomanip> -#include <mutex> -#include <sstream> - -#include <android-base/strings.h> -#include <log/log.h> - -using ::android::base::Join; -using ::android::base::StringPrintf; - -namespace android { -namespace netdutils { - -namespace { - -std::string makeTimestampedEntry(const std::string& entry) { - using ::std::chrono::duration_cast; - using ::std::chrono::milliseconds; - using ::std::chrono::system_clock; - - std::stringstream tsEntry; - const auto now = system_clock::now(); - const auto time_sec = system_clock::to_time_t(now); - tsEntry << std::put_time(std::localtime(&time_sec), "%m-%d %H:%M:%S.") << std::setw(3) - << std::setfill('0') - << duration_cast<milliseconds>(now - system_clock::from_time_t(time_sec)).count() << " " - << entry; - - return tsEntry.str(); -} - -} // namespace - -std::string LogEntry::toString() const { - std::vector<std::string> text; - - if (!mMsg.empty()) text.push_back(mMsg); - if (!mFunc.empty()) { - text.push_back(StringPrintf("%s(%s)", mFunc.c_str(), Join(mArgs, ", ").c_str())); - } - if (!mReturns.empty()) { - text.push_back("->"); - text.push_back(StringPrintf("(%s)", Join(mReturns, ", ").c_str())); - } - if (!mUid.empty()) text.push_back(mUid); - if (!mDuration.empty()) text.push_back(StringPrintf("(%s)", mDuration.c_str())); - - return Join(text, " "); -} - -LogEntry& LogEntry::message(const std::string& message) { - mMsg = message; - return *this; -} - -LogEntry& LogEntry::function(const std::string& function_name) { - mFunc = function_name; - return *this; -} - -LogEntry& LogEntry::prettyFunction(const std::string& pretty_function) { - // __PRETTY_FUNCTION__ generally seems to be of the form: - // - // qualifed::returnType qualified::function(args...) - // - // where the qualified forms include "(anonymous namespace)" in the - // "::"-delimited list and keywords like "virtual" (where applicable). - // - // Here we try to convert strings like: - // - // virtual binder::Status android::net::NetdNativeService::isAlive(bool *) - // netdutils::LogEntry android::netd::(anonymous namespace)::AAA::BBB::function() - // - // into just "NetdNativeService::isAlive" or "BBB::function". Note that - // without imposing convention, how to easily identify any namespace/class - // name boundary is not obvious. - const size_t endFuncName = pretty_function.rfind('('); - const size_t precedingSpace = pretty_function.rfind(' ', endFuncName); - size_t substrStart = (precedingSpace != std::string::npos) ? precedingSpace + 1 : 0; - - const size_t beginFuncName = pretty_function.rfind("::", endFuncName); - if (beginFuncName != std::string::npos && substrStart < beginFuncName) { - const size_t previousNameBoundary = pretty_function.rfind("::", beginFuncName - 1); - if (previousNameBoundary < beginFuncName && substrStart < previousNameBoundary) { - substrStart = previousNameBoundary + 2; - } else { - substrStart = beginFuncName + 2; - } - } - - mFunc = pretty_function.substr(substrStart, endFuncName - substrStart); - return *this; -} - -LogEntry& LogEntry::arg(const std::string& val) { - mArgs.push_back(val.empty() ? "\"\"" : val); - return *this; -} - -template <> -LogEntry& LogEntry::arg<>(bool val) { - mArgs.push_back(val ? "true" : "false"); - return *this; -} - -LogEntry& LogEntry::arg(const std::vector<int32_t>& val) { - mArgs.push_back(StringPrintf("[%s]", Join(val, ", ").c_str())); - return *this; -} - -LogEntry& LogEntry::arg(const std::vector<uint8_t>& val) { - mArgs.push_back('{' + toHex(makeSlice(val)) + '}'); - return *this; -} - -LogEntry& LogEntry::arg(const std::vector<std::string>& val) { - mArgs.push_back(StringPrintf("[%s]", Join(val, ", ").c_str())); - return *this; -} - -LogEntry& LogEntry::returns(const std::string& rval) { - mReturns.push_back(rval); - return *this; -} - -LogEntry& LogEntry::returns(bool rval) { - mReturns.push_back(rval ? "true" : "false"); - return *this; -} - -LogEntry& LogEntry::returns(const Status& status) { - mReturns.push_back(status.msg()); - return *this; -} - -LogEntry& LogEntry::withUid(uid_t uid) { - mUid = StringPrintf("(uid=%d)", uid); - return *this; -} - -LogEntry& LogEntry::withAutomaticDuration() { - using ms = std::chrono::duration<float, std::ratio<1, 1000>>; - - const std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); - std::stringstream duration; - duration << std::setprecision(1) << std::chrono::duration_cast<ms>(end - mStart).count() - << "ms"; - mDuration = duration.str(); - return *this; -} - -LogEntry& LogEntry::withDuration(const std::string& duration) { - mDuration = duration; - return *this; -} - -Log::~Log() { - // TODO: dump the last N entries to the android log for possible posterity. - info(LogEntry().function(__FUNCTION__)); -} - -void Log::forEachEntry(const std::function<void(const std::string&)>& perEntryFn) const { - // We make a (potentially expensive) copy of the log buffer (including - // all strings), in case the |perEntryFn| takes its sweet time. - std::deque<std::string> entries; - { - std::shared_lock<std::shared_mutex> guard(mLock); - entries.assign(mEntries.cbegin(), mEntries.cend()); - } - - for (const std::string& entry : entries) perEntryFn(entry); -} - -void Log::record(Log::Level lvl, const std::string& entry) { - switch (lvl) { - case Level::LOG: - break; - case Level::INFO: - ALOG(LOG_INFO, mTag.c_str(), "%s", entry.c_str()); - break; - case Level::WARN: - ALOG(LOG_WARN, mTag.c_str(), "%s", entry.c_str()); - break; - case Level::ERROR: - ALOG(LOG_ERROR, mTag.c_str(), "%s", entry.c_str()); - break; - } - - std::lock_guard guard(mLock); - mEntries.push_back(makeTimestampedEntry(entry)); - while (mEntries.size() > mMaxEntries) mEntries.pop_front(); -} - -} // namespace netdutils -} // namespace android diff --git a/libnetdutils/LogTest.cpp b/libnetdutils/LogTest.cpp deleted file mode 100644 index 12705609..00000000 --- a/libnetdutils/LogTest.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <gtest/gtest.h> - -#include "netdutils/Log.h" - -android::netdutils::LogEntry globalFunctionName() { - return android::netdutils::LogEntry().function(__FUNCTION__); -} - -android::netdutils::LogEntry globalPrettyFunctionName() { - return android::netdutils::LogEntry().prettyFunction(__PRETTY_FUNCTION__); -} - -namespace android { -namespace netdutils { - -namespace { - -LogEntry functionName() { - return LogEntry().function(__FUNCTION__); -} - -LogEntry prettyFunctionName() { - return LogEntry().prettyFunction(__PRETTY_FUNCTION__); -} - -} // namespace - -class AAA { - public: - AAA() = default; - - LogEntry functionName() { - return LogEntry().function(__FUNCTION__); - } - - LogEntry prettyFunctionName() { - return LogEntry().prettyFunction(__PRETTY_FUNCTION__); - } - - class BBB { - public: - BBB() = default; - - LogEntry functionName() { - return LogEntry().function(__FUNCTION__); - } - - LogEntry prettyFunctionName() { - return LogEntry().prettyFunction(__PRETTY_FUNCTION__); - } - }; -}; - -TEST(LogEntryTest, Empty) { - LogEntry empty; - EXPECT_EQ("", empty.toString()); -} - -TEST(LogEntryTest, GlobalFunction) { - EXPECT_EQ("globalFunctionName()", ::globalFunctionName().toString()); -} - -TEST(LogEntryTest, GlobalPrettyFunction) { - EXPECT_EQ("globalPrettyFunctionName()", ::globalPrettyFunctionName().toString()); -} - -TEST(LogEntryTest, UnnamedNamespaceFunction) { - const LogEntry entry = functionName(); - EXPECT_EQ("functionName()", entry.toString()); -} - -TEST(LogEntryTest, UnnamedNamespacePrettyFunction) { - const LogEntry entry = prettyFunctionName(); - EXPECT_EQ("prettyFunctionName()", entry.toString()); -} - -TEST(LogEntryTest, ClassFunction) { - const LogEntry entry = AAA().functionName(); - EXPECT_EQ("functionName()", entry.toString()); -} - -TEST(LogEntryTest, ClassPrettyFunction) { - const LogEntry entry = AAA().prettyFunctionName(); - EXPECT_EQ("AAA::prettyFunctionName()", entry.toString()); -} - -TEST(LogEntryTest, InnerClassFunction) { - const LogEntry entry = AAA::BBB().functionName(); - EXPECT_EQ("functionName()", entry.toString()); -} - -TEST(LogEntryTest, InnerClassPrettyFunction) { - const LogEntry entry = AAA::BBB().prettyFunctionName(); - EXPECT_EQ("BBB::prettyFunctionName()", entry.toString()); -} - -TEST(LogEntryTest, PrintChainedArguments) { - const LogEntry entry = LogEntry() - .function("testFunc") - .arg("hello") - .arg(42) - .arg(true); - EXPECT_EQ("testFunc(hello, 42, true)", entry.toString()); -} - -TEST(LogEntryTest, PrintIntegralTypes) { - const LogEntry entry = LogEntry() - .function("testFunc") - .arg('A') - .arg(100U) - .arg(-1000LL); - EXPECT_EQ("testFunc(65, 100, -1000)", entry.toString()); -} - -TEST(LogEntryTest, PrintHex) { - const std::vector<uint8_t> buf{0xDE, 0xAD, 0xBE, 0xEF}; - const LogEntry entry = LogEntry().function("testFunc").arg(buf); - EXPECT_EQ("testFunc({deadbeef})", entry.toString()); -} - -TEST(LogEntryTest, PrintArgumentPack) { - const LogEntry entry = LogEntry().function("testFunc").args("hello", 42, false); - EXPECT_EQ("testFunc(hello, 42, false)", entry.toString()); -} - -} // namespace netdutils -} // namespace android diff --git a/libnetdutils/MemBlockTest.cpp b/libnetdutils/MemBlockTest.cpp deleted file mode 100644 index 6455a7e0..00000000 --- a/libnetdutils/MemBlockTest.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <algorithm> -#include <cstdint> -#include <utility> - -#include <gtest/gtest.h> - -#include "netdutils/MemBlock.h" -#include "netdutils/Slice.h" - -namespace android { -namespace netdutils { - -namespace { - -constexpr unsigned DNS_PACKET_SIZE = 512; -constexpr int ARBITRARY_VALUE = 0x55; - -MemBlock makeArbitraryMemBlock(size_t len) { - MemBlock result(len); - // Do some fictional work before returning. - for (Slice slice = result.get(); !slice.empty(); slice = drop(slice, 1)) { - slice.base()[0] = ARBITRARY_VALUE; - } - return result; -} - -void checkAllZeros(Slice slice) { - for (; !slice.empty(); slice = drop(slice, 1)) { - EXPECT_EQ(0U, slice.base()[0]); - } -} - -void checkArbitraryMemBlock(const MemBlock& block, size_t expectedSize) { - Slice slice = block.get(); - EXPECT_EQ(expectedSize, slice.size()); - EXPECT_NE(nullptr, slice.base()); - for (; !slice.empty(); slice = drop(slice, 1)) { - EXPECT_EQ(ARBITRARY_VALUE, slice.base()[0]); - } -} - -void checkHelloMello(Slice dest, Slice src) { - EXPECT_EQ('h', dest.base()[0]); - EXPECT_EQ('e', dest.base()[1]); - EXPECT_EQ('l', dest.base()[2]); - EXPECT_EQ('l', dest.base()[3]); - EXPECT_EQ('o', dest.base()[4]); - - src.base()[0] = 'm'; - EXPECT_EQ('h', dest.base()[0]); -} - -} // namespace - -TEST(MemBlockTest, Empty) { - MemBlock empty; - EXPECT_TRUE(empty.get().empty()); - EXPECT_EQ(nullptr, empty.get().base()); -} - -TEST(MemBlockTest, ExplicitZero) { - MemBlock zero(0); - EXPECT_TRUE(zero.get().empty()); - EXPECT_EQ(nullptr, zero.get().base()); -} - -TEST(MemBlockTest, BasicAllocation) { - MemBlock dnsPacket(DNS_PACKET_SIZE); - Slice slice = dnsPacket.get(); - EXPECT_EQ(DNS_PACKET_SIZE, slice.size()); - // Verify the space is '\0'-initialized. - ASSERT_NO_FATAL_FAILURE(checkAllZeros(slice)); - EXPECT_NE(nullptr, slice.base()); -} - -TEST(MemBlockTest, MoveConstruction) { - MemBlock block(makeArbitraryMemBlock(DNS_PACKET_SIZE)); - ASSERT_NO_FATAL_FAILURE(checkArbitraryMemBlock(block, DNS_PACKET_SIZE)); -} - -TEST(MemBlockTest, MoveAssignmentOrConstruction) { - MemBlock block = makeArbitraryMemBlock(DNS_PACKET_SIZE); - ASSERT_NO_FATAL_FAILURE(checkArbitraryMemBlock(block, DNS_PACKET_SIZE)); -} - -TEST(MemBlockTest, StdMoveAssignment) { - constexpr unsigned SIZE = 10; - - MemBlock block; - EXPECT_TRUE(block.get().empty()); - EXPECT_EQ(nullptr, block.get().base()); - - { - MemBlock block2 = makeArbitraryMemBlock(SIZE); - EXPECT_EQ(SIZE, block2.get().size()); - // More fictional work. - for (unsigned i = 0; i < SIZE; i++) { - block2.get().base()[i] = i; - } - block = std::move(block2); - } - - EXPECT_EQ(SIZE, block.get().size()); - for (unsigned i = 0; i < SIZE; i++) { - EXPECT_EQ(i, block.get().base()[i]); - } -} - -TEST(MemBlockTest, ConstructionFromSlice) { - uint8_t data[] = {'h', 'e', 'l', 'l', 'o'}; - Slice dataSlice(Slice(data, sizeof(data) / sizeof(data[0]))); - - MemBlock dataCopy(dataSlice); - ASSERT_NO_FATAL_FAILURE(checkHelloMello(dataCopy.get(), dataSlice)); -} - -TEST(MemBlockTest, ImplicitCastToSlice) { - uint8_t data[] = {'h', 'e', 'l', 'l', 'o'}; - Slice dataSlice(Slice(data, sizeof(data) / sizeof(data[0]))); - - MemBlock dataCopy(dataSlice.size()); - // NOTE: no explicit MemBlock::get(). - // Verify the space is '\0'-initialized. - ASSERT_NO_FATAL_FAILURE(checkAllZeros(dataCopy)); - copy(dataCopy, dataSlice); - ASSERT_NO_FATAL_FAILURE(checkHelloMello(dataCopy, dataSlice)); -} - -} // namespace netdutils -} // namespace android diff --git a/libnetdutils/Netfilter.cpp b/libnetdutils/Netfilter.cpp deleted file mode 100644 index bb43de0a..00000000 --- a/libnetdutils/Netfilter.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <arpa/inet.h> -#include <linux/netfilter.h> -#include <linux/netfilter/nfnetlink.h> -#include <linux/netlink.h> -#include <ios> - -#include "netdutils/Netfilter.h" - -std::ostream& operator<<(std::ostream& os, const nfgenmsg& msg) { - return os << std::hex << "nfgenmsg[" - << "family: 0x" << static_cast<int>(msg.nfgen_family) << ", version: 0x" - << static_cast<int>(msg.version) << ", res_id: 0x" << ntohs(msg.res_id) << "]" - << std::dec; -} diff --git a/libnetdutils/Netlink.cpp b/libnetdutils/Netlink.cpp deleted file mode 100644 index 824c0f22..00000000 --- a/libnetdutils/Netlink.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <ios> -#include <linux/netlink.h> - -#include "netdutils/Math.h" -#include "netdutils/Netlink.h" - -namespace android { -namespace netdutils { - -void forEachNetlinkMessage(const Slice buf, - const std::function<void(const nlmsghdr&, const Slice)>& onMsg) { - Slice tail = buf; - while (tail.size() >= sizeof(nlmsghdr)) { - nlmsghdr hdr = {}; - extract(tail, hdr); - const auto len = std::max<size_t>(hdr.nlmsg_len, sizeof(hdr)); - onMsg(hdr, drop(take(tail, len), sizeof(hdr))); - tail = drop(tail, align(len, 2)); - } -} - -void forEachNetlinkAttribute(const Slice buf, - const std::function<void(const nlattr&, const Slice)>& onAttr) { - Slice tail = buf; - while (tail.size() >= sizeof(nlattr)) { - nlattr hdr = {}; - extract(tail, hdr); - const auto len = std::max<size_t>(hdr.nla_len, sizeof(hdr)); - onAttr(hdr, drop(take(tail, len), sizeof(hdr))); - tail = drop(tail, align(len, 2)); - } -} - -} // namespace netdutils -} // namespace android - -bool operator==(const sockaddr_nl& lhs, const sockaddr_nl& rhs) { - return (lhs.nl_family == rhs.nl_family) && (lhs.nl_pid == rhs.nl_pid) && - (lhs.nl_groups == rhs.nl_groups); -} - -bool operator!=(const sockaddr_nl& lhs, const sockaddr_nl& rhs) { - return !(lhs == rhs); -} - -std::ostream& operator<<(std::ostream& os, const nlmsghdr& hdr) { - return os << std::hex << "nlmsghdr[" - << "len: 0x" << hdr.nlmsg_len << ", type: 0x" << hdr.nlmsg_type << ", flags: 0x" - << hdr.nlmsg_flags << ", seq: 0x" << hdr.nlmsg_seq << ", pid: 0x" << hdr.nlmsg_pid - << "]" << std::dec; -} - -std::ostream& operator<<(std::ostream& os, const nlattr& attr) { - return os << std::hex << "nlattr[" - << "len: 0x" << attr.nla_len << ", type: 0x" << attr.nla_type << "]" << std::dec; -} - -std::ostream& operator<<(std::ostream& os, const sockaddr_nl& addr) { - return os << std::hex << "sockaddr_nl[" - << "family: " << addr.nl_family << ", pid: " << addr.nl_pid - << ", groups: " << addr.nl_groups << "]" << std::dec; -} diff --git a/libnetdutils/Slice.cpp b/libnetdutils/Slice.cpp deleted file mode 100644 index 7a07d477..00000000 --- a/libnetdutils/Slice.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <sstream> - -#include "netdutils/Slice.h" - -namespace android { -namespace netdutils { -namespace { - -// Convert one byte to a two character hexadecimal string -const std::string toHex(uint8_t byte) { - const std::array<char, 16> kLookup = { - {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}}; - return {kLookup[byte >> 4], kLookup[byte & 0xf]}; -} - -} // namespace - -std::string toString(const Slice s) { - return std::string(reinterpret_cast<char*>(s.base()), s.size()); -} - -std::string toHex(const Slice s, int wrap) { - Slice tail = s; - int count = 0; - std::stringstream ss; - while (!tail.empty()) { - uint8_t byte = 0; - extract(tail, byte); - ss << toHex(byte); - if ((++count % wrap) == 0) { - ss << "\n"; - } - tail = drop(tail, 1); - } - return ss.str(); -} - -std::ostream& operator<<(std::ostream& os, const Slice& slice) { - return os << std::hex << "Slice[base: " << reinterpret_cast<void*>(slice.base()) - << ", limit: " << reinterpret_cast<void*>(slice.limit()) << ", size: 0x" - << slice.size() << "]" << std::dec; -} - -} // namespace netdutils -} // namespace android diff --git a/libnetdutils/SliceTest.cpp b/libnetdutils/SliceTest.cpp deleted file mode 100644 index a4969331..00000000 --- a/libnetdutils/SliceTest.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <array> -#include <cstdint> - -#include <gtest/gtest.h> - -#include "netdutils/Slice.h" -#include "netdutils/Status.h" -#include "netdutils/StatusOr.h" - -namespace android { -namespace netdutils { - -class SliceTest : public testing::Test { - protected: - std::array<char, 256> mRaw = {}; -}; - -TEST_F(SliceTest, smoke) { - Slice s1 = makeSlice(mRaw); - Slice s2 = makeSlice(mRaw); - auto p = split(s1, 14); - s2 = p.first; // avoid warn-unused error - std::stringstream ss; - ss << Slice(); - EXPECT_EQ("Slice[base: 0x0, limit: 0x0, size: 0x0]", ss.str()); - constexpr size_t kBytes = 14; - EXPECT_EQ(s1.base(), take(s1, kBytes).base()); - EXPECT_EQ(kBytes, take(s1, kBytes).size()); - EXPECT_EQ(s1.base() + kBytes, drop(s1, kBytes).base()); - EXPECT_EQ(s1.size() - kBytes, drop(s1, kBytes).size()); - double a = 0; - double b = 0; - int c = 0; - EXPECT_EQ(sizeof(a), extract(s1, a)); - EXPECT_EQ(sizeof(a) + sizeof(b), extract(s1, a, b)); - EXPECT_EQ(sizeof(a) + sizeof(b) + sizeof(c), extract(s1, a, b, c)); -} - -TEST_F(SliceTest, constructor) { - // Expect the following lines to compile - Slice s1 = makeSlice(mRaw); - Slice s2(s1); - Slice s3 = s2; - const Slice s4(s3); - const Slice s5 = s4; - s3 = s5; - Slice s6(mRaw.data(), mRaw.size()); - Slice s7(mRaw.data(), mRaw.data() + mRaw.size()); - struct { - int a; - double b; - float c; - } anon; - makeSlice(anon); - EXPECT_EQ(reinterpret_cast<uint8_t*>(mRaw.data()), s1.base()); - EXPECT_EQ(reinterpret_cast<uint8_t*>(mRaw.data()) + mRaw.size(), s1.limit()); - EXPECT_EQ(mRaw.size(), s1.size()); - EXPECT_FALSE(mRaw.empty()); - EXPECT_TRUE(Slice().empty()); - EXPECT_TRUE(Slice(nullptr, static_cast<size_t>(0)).empty()); - EXPECT_TRUE(Slice(nullptr, nullptr).empty()); -} - -TEST_F(SliceTest, extract) { - struct A { - int a, b; - bool operator==(const A& other) const { return a == other.a && b == other.b; } - }; - struct B { - char str[12]; - bool b; - int i; - bool operator==(const B& other) const { - return b == other.b && i == other.i && 0 == strncmp(str, other.str, 12); - } - }; - - A origA1 = {1, 2}; - A origA2 = {3, 4}; - B origB = {"hello world", true, 1234}; - - // Populate buffer for extracting. - Slice buffer = makeSlice(mRaw); - copy(buffer, makeSlice(origA1)); - copy(drop(buffer, sizeof(origA1)), makeSlice(origB)); - copy(drop(buffer, sizeof(origA1) + sizeof(origB)), makeSlice(origA2)); - - { - // Non-variadic extract - A a1{}; - size_t len = extract(buffer, a1); - EXPECT_EQ(sizeof(A), len); - EXPECT_EQ(origA1, a1); - } - - { - // Variadic extract, 2 destinations - A a1{}; - B b{}; - size_t len = extract(buffer, a1, b); - EXPECT_EQ(sizeof(A) + sizeof(B), len); - EXPECT_EQ(origA1, a1); - EXPECT_EQ(origB, b); - } - - { - // Variadic extract, 3 destinations - A a1{}, a2{}; - B b{}; - size_t len = extract(buffer, a1, b, a2); - EXPECT_EQ(2 * sizeof(A) + sizeof(B), len); - EXPECT_EQ(origA1, a1); - EXPECT_EQ(origB, b); - EXPECT_EQ(origA2, a2); - } -} - -} // namespace netdutils -} // namespace android diff --git a/libnetdutils/Socket.cpp b/libnetdutils/Socket.cpp deleted file mode 100644 index e962b6e5..00000000 --- a/libnetdutils/Socket.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <arpa/inet.h> - -#include "netdutils/Slice.h" -#include "netdutils/Socket.h" - -namespace android { -namespace netdutils { - -StatusOr<std::string> toString(const in6_addr& addr) { - std::array<char, INET6_ADDRSTRLEN> out = {}; - auto* rv = inet_ntop(AF_INET6, &addr, out.data(), out.size()); - if (rv == nullptr) { - return statusFromErrno(errno, "inet_ntop() failed"); - } - return std::string(out.data()); -} - -} // namespace netdutils -} // namespace android diff --git a/libnetdutils/SocketOption.cpp b/libnetdutils/SocketOption.cpp deleted file mode 100644 index 023df6e8..00000000 --- a/libnetdutils/SocketOption.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "netdutils/SocketOption.h" - -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <sys/socket.h> -#include <utility> - -#include "netdutils/Syscalls.h" - -namespace android { -namespace netdutils { - -Status enableSockopt(Fd sock, int level, int optname) { - auto& sys = sSyscalls.get(); - const int on = 1; - return sys.setsockopt(sock, level, optname, &on, sizeof(on)); -} - -Status enableTcpKeepAlives(Fd sock, unsigned idleTime, unsigned numProbes, unsigned probeInterval) { - RETURN_IF_NOT_OK(enableSockopt(sock, SOL_SOCKET, SO_KEEPALIVE)); - - auto& sys = sSyscalls.get(); - if (idleTime != 0) { - RETURN_IF_NOT_OK(sys.setsockopt(sock, SOL_TCP, TCP_KEEPIDLE, &idleTime, sizeof(idleTime))); - } - if (numProbes != 0) { - RETURN_IF_NOT_OK(sys.setsockopt(sock, SOL_TCP, TCP_KEEPCNT, &numProbes, sizeof(numProbes))); - } - if (probeInterval != 0) { - RETURN_IF_NOT_OK(sys.setsockopt(sock, SOL_TCP, TCP_KEEPINTVL, &probeInterval, - sizeof(probeInterval))); - } - - return status::ok; -} - -} // namespace netdutils -} // namespace android diff --git a/libnetdutils/Status.cpp b/libnetdutils/Status.cpp deleted file mode 100644 index acd8f11a..00000000 --- a/libnetdutils/Status.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "netdutils/Status.h" - -#include <sstream> - -#include "android-base/stringprintf.h" - -namespace android { -namespace netdutils { - -Status statusFromErrno(int err, const std::string& msg) { - return Status(err, base::StringPrintf("[%s] : %s", strerror(err), msg.c_str())); -} - -bool equalToErrno(const Status& status, int err) { - return status.code() == err; -} - -std::string toString(const Status& status) { - std::stringstream ss; - ss << status; - return ss.str(); -} - -std::ostream& operator<<(std::ostream& os, const Status& s) { - return os << "Status[code: " << s.code() << ", msg: \"" << s.msg() << "\"]"; -} - -} // namespace netdutils -} // namespace android diff --git a/libnetdutils/StatusTest.cpp b/libnetdutils/StatusTest.cpp deleted file mode 100644 index 4cfc3bbb..00000000 --- a/libnetdutils/StatusTest.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "netdutils/Status.h" -#include "netdutils/StatusOr.h" - -#include <sstream> - -#include <gtest/gtest.h> - -namespace android { -namespace netdutils { -namespace { - -TEST(StatusTest, valueSemantics) { - // Default constructor - EXPECT_EQ(status::ok, Status()); - - // Copy constructor - Status status1(1); - Status status2(status1); // NOLINT(performance-unnecessary-copy-initialization) - EXPECT_EQ(1, status2.code()); - - // Copy assignment - Status status3; - status3 = status2; - EXPECT_EQ(1, status3.code()); - - // Same with const objects - const Status status4(4); - const Status status5(status4); // NOLINT(performance-unnecessary-copy-initialization) - Status status6; - status6 = status5; - EXPECT_EQ(4, status6.code()); -} - -TEST(StatusTest, errorMessages) { - Status s(42, "for tea too"); - EXPECT_EQ(42, s.code()); - EXPECT_FALSE(s.ok()); - EXPECT_EQ(s.msg(), "for tea too"); -} - -TEST(StatusOrTest, moveSemantics) { - // Status objects should be cheaply movable. - EXPECT_TRUE(std::is_nothrow_move_constructible<Status>::value); - EXPECT_TRUE(std::is_nothrow_move_assignable<Status>::value); - - // Should move from a temporary Status (twice) - Status s(Status(Status(42, "move me"))); - EXPECT_EQ(42, s.code()); - EXPECT_EQ(s.msg(), "move me"); - - Status s2(666, "EDAEMON"); - EXPECT_NE(s, s2); - s = s2; // Invokes the move-assignment operator. - EXPECT_EQ(666, s.code()); - EXPECT_EQ(s.msg(), "EDAEMON"); - EXPECT_EQ(s, s2); - - // A moved-from Status can be re-used. - s2 = s; - - // Now both objects are valid. - EXPECT_EQ(666, s.code()); - EXPECT_EQ(s.msg(), "EDAEMON"); - EXPECT_EQ(s, s2); -} - -TEST(StatusTest, ignoredStatus) { - statusFromErrno(ENOTTY, "Not a typewriter, what did you expect?").ignoreError(); -} - -TEST(StatusOrTest, ostream) { - { - StatusOr<int> so(11); - std::stringstream ss; - ss << so; - // TODO: Fix StatusOr to optionally output "value:". - EXPECT_EQ("StatusOr[status: Status[code: 0, msg: \"\"]]", ss.str()); - } - { - StatusOr<int> err(status::undefined); - std::stringstream ss; - ss << err; - EXPECT_EQ("StatusOr[status: Status[code: 2147483647, msg: \"undefined\"]]", ss.str()); - } -} - -} // namespace -} // namespace netdutils -} // namespace android diff --git a/libnetdutils/Syscalls.cpp b/libnetdutils/Syscalls.cpp deleted file mode 100644 index 9f653f70..00000000 --- a/libnetdutils/Syscalls.cpp +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "netdutils/Syscalls.h" - -#include <atomic> -#include <type_traits> -#include <utility> - -namespace android { -namespace netdutils { -namespace { - -// Retry syscall fn as long as it returns -1 with errno == EINTR -template <typename FnT, typename... Params> -typename std::result_of<FnT(Params...)>::type syscallRetry(FnT fn, Params&&... params) { - auto rv = fn(std::forward<Params>(params)...); - while ((rv == -1) && (errno == EINTR)) { - rv = fn(std::forward<Params>(params)...); - } - return rv; -} - -} // namespace - -// Production implementation of Syscalls that forwards to libc syscalls. -class RealSyscalls final : public Syscalls { - public: - ~RealSyscalls() override = default; - - StatusOr<UniqueFd> open(const std::string& pathname, int flags, mode_t mode) const override { - UniqueFd fd(::open(pathname.c_str(), flags, mode)); - if (!isWellFormed(fd)) { - return statusFromErrno(errno, "open(\"" + pathname + "\"...) failed"); - } - return fd; - } - - StatusOr<UniqueFd> socket(int domain, int type, int protocol) const override { - UniqueFd sock(::socket(domain, type, protocol)); - if (!isWellFormed(sock)) { - return statusFromErrno(errno, "socket() failed"); - } - return sock; - } - - Status getsockname(Fd sock, sockaddr* addr, socklen_t* addrlen) const override { - auto rv = ::getsockname(sock.get(), addr, addrlen); - if (rv == -1) { - return statusFromErrno(errno, "getsockname() failed"); - } - return status::ok; - } - - Status getsockopt(Fd sock, int level, int optname, void* optval, - socklen_t* optlen) const override { - auto rv = ::getsockopt(sock.get(), level, optname, optval, optlen); - if (rv == -1) { - return statusFromErrno(errno, "getsockopt() failed"); - } - return status::ok; - } - - Status setsockopt(Fd sock, int level, int optname, const void* optval, - socklen_t optlen) const override { - auto rv = ::setsockopt(sock.get(), level, optname, optval, optlen); - if (rv == -1) { - return statusFromErrno(errno, "setsockopt() failed"); - } - return status::ok; - } - - Status bind(Fd sock, const sockaddr* addr, socklen_t addrlen) const override { - auto rv = ::bind(sock.get(), addr, addrlen); - if (rv == -1) { - return statusFromErrno(errno, "bind() failed"); - } - return status::ok; - } - - Status connect(Fd sock, const sockaddr* addr, socklen_t addrlen) const override { - auto rv = syscallRetry(::connect, sock.get(), addr, addrlen); - if (rv == -1) { - return statusFromErrno(errno, "connect() failed"); - } - return status::ok; - } - - StatusOr<ifreq> ioctl(Fd sock, unsigned long request, ifreq* ifr) const override { - auto rv = ::ioctl(sock.get(), request, ifr); - if (rv == -1) { - return statusFromErrno(errno, "ioctl() failed"); - } - return *ifr; - } - - StatusOr<UniqueFd> eventfd(unsigned int initval, int flags) const override { - UniqueFd fd(::eventfd(initval, flags)); - if (!isWellFormed(fd)) { - return statusFromErrno(errno, "eventfd() failed"); - } - return fd; - } - - StatusOr<int> ppoll(pollfd* fds, nfds_t nfds, double timeout) const override { - timespec ts = {}; - ts.tv_sec = timeout; - ts.tv_nsec = (timeout - ts.tv_sec) * 1e9; - auto rv = syscallRetry(::ppoll, fds, nfds, &ts, nullptr); - if (rv == -1) { - return statusFromErrno(errno, "ppoll() failed"); - } - return rv; - } - - StatusOr<size_t> writev(Fd fd, const std::vector<iovec>& iov) const override { - auto rv = syscallRetry(::writev, fd.get(), iov.data(), iov.size()); - if (rv == -1) { - return statusFromErrno(errno, "writev() failed"); - } - return rv; - } - - StatusOr<size_t> write(Fd fd, const Slice buf) const override { - auto rv = syscallRetry(::write, fd.get(), buf.base(), buf.size()); - if (rv == -1) { - return statusFromErrno(errno, "write() failed"); - } - return static_cast<size_t>(rv); - } - - StatusOr<Slice> read(Fd fd, const Slice buf) const override { - auto rv = syscallRetry(::read, fd.get(), buf.base(), buf.size()); - if (rv == -1) { - return statusFromErrno(errno, "read() failed"); - } - return Slice(buf.base(), rv); - } - - StatusOr<size_t> sendto(Fd sock, const Slice buf, int flags, const sockaddr* dst, - socklen_t dstlen) const override { - auto rv = syscallRetry(::sendto, sock.get(), buf.base(), buf.size(), flags, dst, dstlen); - if (rv == -1) { - return statusFromErrno(errno, "sendto() failed"); - } - return static_cast<size_t>(rv); - } - - StatusOr<Slice> recvfrom(Fd sock, const Slice dst, int flags, sockaddr* src, - socklen_t* srclen) const override { - auto rv = syscallRetry(::recvfrom, sock.get(), dst.base(), dst.size(), flags, src, srclen); - if (rv == -1) { - return statusFromErrno(errno, "recvfrom() failed"); - } - if (rv == 0) { - return status::eof; - } - return take(dst, rv); - } - - Status shutdown(Fd fd, int how) const override { - auto rv = ::shutdown(fd.get(), how); - if (rv == -1) { - return statusFromErrno(errno, "shutdown() failed"); - } - return status::ok; - } - - Status close(Fd fd) const override { - auto rv = ::close(fd.get()); - if (rv == -1) { - return statusFromErrno(errno, "close() failed"); - } - return status::ok; - } - - StatusOr<UniqueFile> fopen(const std::string& path, const std::string& mode) const override { - UniqueFile file(::fopen(path.c_str(), mode.c_str())); - if (file == nullptr) { - return statusFromErrno(errno, "fopen(\"" + path + "\", \"" + mode + "\") failed"); - } - return file; - } - - StatusOr<pid_t> fork() const override { - pid_t rv = ::fork(); - if (rv == -1) { - return statusFromErrno(errno, "fork() failed"); - } - return rv; - } - - StatusOr<int> vfprintf(FILE* file, const char* format, va_list ap) const override { - auto rv = ::vfprintf(file, format, ap); - if (rv == -1) { - return statusFromErrno(errno, "vfprintf() failed"); - } - return rv; - } - - StatusOr<int> vfscanf(FILE* file, const char* format, va_list ap) const override { - auto rv = ::vfscanf(file, format, ap); - if (rv == -1) { - return statusFromErrno(errno, "vfscanf() failed"); - } - return rv; - } - - Status fclose(FILE* file) const override { - auto rv = ::fclose(file); - if (rv == -1) { - return statusFromErrno(errno, "fclose() failed"); - } - return status::ok; - } -}; - -SyscallsHolder::~SyscallsHolder() { - delete &get(); -} - -Syscalls& SyscallsHolder::get() { - while (true) { - // memory_order_relaxed gives the compiler and hardware more - // freedom. If we get a stale value (this should only happen - // early in the execution of a program) the exchange code below - // will loop until we get the most current value. - auto* syscalls = mSyscalls.load(std::memory_order_relaxed); - // Common case returns existing syscalls - if (syscalls) { - return *syscalls; - } - - // This code will execute on first get() - std::unique_ptr<Syscalls> tmp(new RealSyscalls()); - Syscalls* expected = nullptr; - bool success = mSyscalls.compare_exchange_strong(expected, tmp.get()); - if (success) { - // Ownership was transferred to mSyscalls already, must release() - return *tmp.release(); - } - } -} - -Syscalls& SyscallsHolder::swap(Syscalls& syscalls) { - return *mSyscalls.exchange(&syscalls); -} - -SyscallsHolder sSyscalls; - -} // namespace netdutils -} // namespace android diff --git a/libnetdutils/SyscallsTest.cpp b/libnetdutils/SyscallsTest.cpp deleted file mode 100644 index 78ffab5e..00000000 --- a/libnetdutils/SyscallsTest.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <array> -#include <cstdint> -#include <memory> - -#include <gtest/gtest.h> - -#include "netdutils/Handle.h" -#include "netdutils/Math.h" -#include "netdutils/MockSyscalls.h" -#include "netdutils/Netfilter.h" -#include "netdutils/Netlink.h" -#include "netdutils/Slice.h" -#include "netdutils/Status.h" -#include "netdutils/StatusOr.h" -#include "netdutils/Syscalls.h" - -using testing::_; -using testing::ByMove; -using testing::Invoke; -using testing::Return; -using testing::StrictMock; - -namespace android { -namespace netdutils { - -class SyscallsTest : public testing::Test { - protected: - StrictMock<ScopedMockSyscalls> mSyscalls; -}; - -TEST(syscalls, scopedMock) { - auto& old = sSyscalls.get(); - { - StrictMock<ScopedMockSyscalls> s; - EXPECT_EQ(&s, &sSyscalls.get()); - } - EXPECT_EQ(&old, &sSyscalls.get()); -} - -TEST_F(SyscallsTest, open) { - const char kPath[] = "/test/path/please/ignore"; - constexpr Fd kFd(40); - constexpr int kFlags = 883; - constexpr mode_t kMode = 37373; - const auto& sys = sSyscalls.get(); - EXPECT_CALL(mSyscalls, open(kPath, kFlags, kMode)).WillOnce(Return(ByMove(UniqueFd(kFd)))); - EXPECT_CALL(mSyscalls, close(kFd)).WillOnce(Return(status::ok)); - auto result = sys.open(kPath, kFlags, kMode); - EXPECT_EQ(status::ok, result.status()); - EXPECT_EQ(kFd, result.value()); -} - -TEST_F(SyscallsTest, getsockname) { - constexpr Fd kFd(40); - sockaddr_nl expected = {}; - auto& sys = sSyscalls.get(); - - // Success - EXPECT_CALL(mSyscalls, getsockname(kFd, _, _)) - .WillOnce(Invoke([expected](Fd, sockaddr* addr, socklen_t* addrlen) { - memcpy(addr, &expected, sizeof(expected)); - EXPECT_EQ(*addrlen, static_cast<socklen_t>(sizeof(expected))); - return status::ok; - })); - const auto result = sys.getsockname<sockaddr_nl>(kFd); - EXPECT_TRUE(isOk(result)); - EXPECT_EQ(expected, result.value()); - - // Failure - const Status kError = statusFromErrno(EINVAL, "test"); - EXPECT_CALL(mSyscalls, getsockname(kFd, _, _)).WillOnce(Return(kError)); - EXPECT_EQ(kError, sys.getsockname<sockaddr_nl>(kFd).status()); -} - -TEST_F(SyscallsTest, setsockopt) { - constexpr Fd kFd(40); - constexpr int kLevel = 50; - constexpr int kOptname = 70; - sockaddr_nl expected = {}; - auto& sys = sSyscalls.get(); - - // Success - EXPECT_CALL(mSyscalls, setsockopt(kFd, kLevel, kOptname, &expected, sizeof(expected))) - .WillOnce(Return(status::ok)); - EXPECT_EQ(status::ok, sys.setsockopt(kFd, kLevel, kOptname, expected)); - - // Failure - const Status kError = statusFromErrno(EINVAL, "test"); - EXPECT_CALL(mSyscalls, setsockopt(kFd, kLevel, kOptname, &expected, sizeof(expected))) - .WillOnce(Return(kError)); - EXPECT_EQ(kError, sys.setsockopt(kFd, kLevel, kOptname, expected)); -} - -TEST_F(SyscallsTest, getsockopt) { - constexpr Fd kFd(40); - constexpr int kLevel = 50; - constexpr int kOptname = 70; - sockaddr_nl expected = {}; - socklen_t optLen = 0; - auto& sys = sSyscalls.get(); - - // Success - EXPECT_CALL(mSyscalls, getsockopt(kFd, kLevel, kOptname, &expected, &optLen)) - .WillOnce(Return(status::ok)); - EXPECT_EQ(status::ok, sys.getsockopt(kFd, kLevel, kOptname, &expected, &optLen)); - - // Failure - const Status kError = statusFromErrno(EINVAL, "test"); - EXPECT_CALL(mSyscalls, getsockopt(kFd, kLevel, kOptname, &expected, &optLen)) - .WillOnce(Return(kError)); - EXPECT_EQ(kError, sys.getsockopt(kFd, kLevel, kOptname, &expected, &optLen)); -} - -TEST_F(SyscallsTest, bind) { - constexpr Fd kFd(40); - sockaddr_nl expected = {}; - auto& sys = sSyscalls.get(); - - // Success - EXPECT_CALL(mSyscalls, bind(kFd, asSockaddrPtr(&expected), sizeof(expected))) - .WillOnce(Return(status::ok)); - EXPECT_EQ(status::ok, sys.bind(kFd, expected)); - - // Failure - const Status kError = statusFromErrno(EINVAL, "test"); - EXPECT_CALL(mSyscalls, bind(kFd, asSockaddrPtr(&expected), sizeof(expected))) - .WillOnce(Return(kError)); - EXPECT_EQ(kError, sys.bind(kFd, expected)); -} - -TEST_F(SyscallsTest, connect) { - constexpr Fd kFd(40); - sockaddr_nl expected = {}; - auto& sys = sSyscalls.get(); - - // Success - EXPECT_CALL(mSyscalls, connect(kFd, asSockaddrPtr(&expected), sizeof(expected))) - .WillOnce(Return(status::ok)); - EXPECT_EQ(status::ok, sys.connect(kFd, expected)); - - // Failure - const Status kError = statusFromErrno(EINVAL, "test"); - EXPECT_CALL(mSyscalls, connect(kFd, asSockaddrPtr(&expected), sizeof(expected))) - .WillOnce(Return(kError)); - EXPECT_EQ(kError, sys.connect(kFd, expected)); -} - -TEST_F(SyscallsTest, sendto) { - constexpr Fd kFd(40); - constexpr int kFlags = 0; - std::array<char, 10> payload; - const auto slice = makeSlice(payload); - sockaddr_nl expected = {}; - auto& sys = sSyscalls.get(); - - // Success - EXPECT_CALL(mSyscalls, sendto(kFd, slice, kFlags, asSockaddrPtr(&expected), sizeof(expected))) - .WillOnce(Return(slice.size())); - EXPECT_EQ(status::ok, sys.sendto(kFd, slice, kFlags, expected)); -} - -TEST_F(SyscallsTest, recvfrom) { - constexpr Fd kFd(40); - constexpr int kFlags = 0; - std::array<char, 10> payload; - const auto dst = makeSlice(payload); - const auto used = take(dst, 8); - sockaddr_nl expected = {}; - auto& sys = sSyscalls.get(); - - // Success - EXPECT_CALL(mSyscalls, recvfrom(kFd, dst, kFlags, _, _)) - .WillOnce(Invoke( - [expected, used](Fd, const Slice, int, sockaddr* src, socklen_t* srclen) { - *srclen = sizeof(expected); - memcpy(src, &expected, *srclen); - return used; - })); - auto result = sys.recvfrom<sockaddr_nl>(kFd, dst, kFlags); - EXPECT_EQ(status::ok, result.status()); - EXPECT_EQ(used, result.value().first); - EXPECT_EQ(expected, result.value().second); -} - -} // namespace netdutils -} // namespace android diff --git a/libnetdutils/ThreadUtilTest.cpp b/libnetdutils/ThreadUtilTest.cpp deleted file mode 100644 index 8fad8b8e..00000000 --- a/libnetdutils/ThreadUtilTest.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <string> - -#include <android-base/expected.h> -#include <gtest/gtest.h> -#include <netdutils/ThreadUtil.h> - -namespace android::netdutils { - -namespace { - -android::base::expected<std::string, int> getThreadName() { - char name[16] = {}; - if (const int ret = pthread_getname_np(pthread_self(), name, sizeof(name)); ret != 0) { - return android::base::unexpected(ret); - } - return std::string(name); -} - -class NoopRun { - public: - explicit NoopRun(const std::string& name = "") : mName(name) { instanceNum++; } - - // Destructor happens in the thread. - ~NoopRun() { - if (checkName) { - auto expected = getThreadName(); - EXPECT_TRUE(expected.has_value()); - EXPECT_EQ(mExpectedName, expected.value()); - } - instanceNum--; - } - - void run() {} - - std::string threadName() { return mName; } - - // Set the expected thread name which will be used to check if it matches the actual thread - // name which is returned from the system call. The check will happen in the destructor. - void setExpectedName(const std::string& expectedName) { - checkName = true; - mExpectedName = expectedName; - } - - static bool waitForAllReleased(int timeoutMs) { - constexpr int intervalMs = 20; - int limit = timeoutMs / intervalMs; - for (int i = 1; i < limit; i++) { - if (instanceNum == 0) { - return true; - } - usleep(intervalMs * 1000); - } - return false; - } - - // To track how many instances are alive. - static std::atomic<int> instanceNum; - - private: - std::string mName; - std::string mExpectedName; - bool checkName = false; -}; - -std::atomic<int> NoopRun::instanceNum; - -} // namespace - -TEST(ThreadUtilTest, objectReleased) { - NoopRun::instanceNum = 0; - NoopRun* obj = new NoopRun(); - EXPECT_EQ(1, NoopRun::instanceNum); - threadLaunch(obj); - - // Wait for the object released along with the thread exited. - EXPECT_TRUE(NoopRun::waitForAllReleased(1000)); - EXPECT_EQ(0, NoopRun::instanceNum); -} - -TEST(ThreadUtilTest, SetThreadName) { - NoopRun::instanceNum = 0; - - // Test thread name empty. - NoopRun* obj1 = new NoopRun(); - obj1->setExpectedName(""); - - // Test normal case. - NoopRun* obj2 = new NoopRun("TestName"); - obj2->setExpectedName("TestName"); - - // Test thread name too long. - std::string name("TestNameTooooLong"); - NoopRun* obj3 = new NoopRun(name); - obj3->setExpectedName(name.substr(0, 15)); - - // Thread names are examined in their destructors. - EXPECT_EQ(3, NoopRun::instanceNum); - threadLaunch(obj1); - threadLaunch(obj2); - threadLaunch(obj3); - - EXPECT_TRUE(NoopRun::waitForAllReleased(1000)); - EXPECT_EQ(0, NoopRun::instanceNum); -} - -} // namespace android::netdutils diff --git a/libnetdutils/UniqueFd.cpp b/libnetdutils/UniqueFd.cpp deleted file mode 100644 index 1cb30edd..00000000 --- a/libnetdutils/UniqueFd.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <algorithm> - -#include "netdutils/UniqueFd.h" -#include "netdutils/Syscalls.h" - -namespace android { -namespace netdutils { - -void UniqueFd::reset(Fd fd) { - auto& sys = sSyscalls.get(); - std::swap(fd, mFd); - if (isWellFormed(fd)) { - expectOk(sys.close(fd)); - } -} - -std::ostream& operator<<(std::ostream& os, const UniqueFd& fd) { - return os << "UniqueFd[" << static_cast<Fd>(fd) << "]"; -} - -} // namespace netdutils -} // namespace android diff --git a/libnetdutils/UniqueFile.cpp b/libnetdutils/UniqueFile.cpp deleted file mode 100644 index 21e87798..00000000 --- a/libnetdutils/UniqueFile.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <algorithm> - -#include "netdutils/Syscalls.h" -#include "netdutils/UniqueFile.h" - -namespace android { -namespace netdutils { - -void UniqueFileDtor::operator()(FILE* file) const { - const auto& sys = sSyscalls.get(); - sys.fclose(file).ignoreError(); -} - -} // namespace netdutils -} // namespace android diff --git a/libnetdutils/include/netdutils/BackoffSequence.h b/libnetdutils/include/netdutils/BackoffSequence.h deleted file mode 100644 index a52e72d6..00000000 --- a/libnetdutils/include/netdutils/BackoffSequence.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NETDUTILS_BACKOFFSEQUENCE_H -#define NETDUTILS_BACKOFFSEQUENCE_H - -#include <stdint.h> -#include <algorithm> -#include <chrono> -#include <limits> - -namespace android { -namespace netdutils { - -// Encapsulate some RFC 3315 section 14 -style backoff mechanics. -// -// https://tools.ietf.org/html/rfc3315#section-14 -template<typename time_type = std::chrono::seconds, typename counter_type = uint32_t> -class BackoffSequence { - public: - struct Parameters { - time_type initialRetransTime{TIME_UNITY}; - counter_type maxRetransCount{0U}; - time_type maxRetransTime{TIME_ZERO}; - time_type maxRetransDuration{TIME_ZERO}; - time_type endOfSequenceIndicator{TIME_ZERO}; - }; - - BackoffSequence() : BackoffSequence(Parameters{}) {} - BackoffSequence(const BackoffSequence &) = default; - BackoffSequence(BackoffSequence &&) = default; - BackoffSequence& operator=(const BackoffSequence &) = default; - BackoffSequence& operator=(BackoffSequence &&) = default; - - bool hasNextTimeout() const noexcept { - return !maxRetransCountExceed() && !maxRetransDurationExceeded(); - } - - // Returns 0 when the sequence is exhausted. - time_type getNextTimeout() { - if (!hasNextTimeout()) return getEndOfSequenceIndicator(); - - mRetransTime = getNextTimeoutAfter(mRetransTime); - - mRetransCount++; - mTotalRetransDuration += mRetransTime; - return mRetransTime; - } - - time_type getEndOfSequenceIndicator() const noexcept { - return mParams.endOfSequenceIndicator; - } - - class Builder { - public: - Builder() {} - - constexpr Builder& withInitialRetransmissionTime(time_type irt) { - mParams.initialRetransTime = irt; - return *this; - } - constexpr Builder& withMaximumRetransmissionCount(counter_type mrc) { - mParams.maxRetransCount = mrc; - return *this; - } - constexpr Builder& withMaximumRetransmissionTime(time_type mrt) { - mParams.maxRetransTime = mrt; - return *this; - } - constexpr Builder& withMaximumRetransmissionDuration(time_type mrd) { - mParams.maxRetransDuration = mrd; - return *this; - } - constexpr Builder& withEndOfSequenceIndicator(time_type eos) { - mParams.endOfSequenceIndicator = eos; - return *this; - } - - constexpr BackoffSequence build() const { - return BackoffSequence(mParams); - } - - private: - Parameters mParams; - }; - - private: - static constexpr int PER_ITERATION_SCALING_FACTOR = 2; - static constexpr time_type TIME_ZERO = time_type(); - static constexpr time_type TIME_UNITY = time_type(1); - - constexpr BackoffSequence(const struct Parameters ¶ms) - : mParams(params), - mRetransCount(0), - mRetransTime(TIME_ZERO), - mTotalRetransDuration(TIME_ZERO) {} - - constexpr bool maxRetransCountExceed() const { - return (mParams.maxRetransCount > 0) && (mRetransCount >= mParams.maxRetransCount); - } - - constexpr bool maxRetransDurationExceeded() const { - return (mParams.maxRetransDuration > TIME_ZERO) && - (mTotalRetransDuration >= mParams.maxRetransDuration); - } - - time_type getNextTimeoutAfter(time_type lastTimeout) const { - // TODO: Support proper random jitter. Also, consider supporting some - // per-iteration scaling factor other than doubling. - time_type nextTimeout = (lastTimeout > TIME_ZERO) - ? PER_ITERATION_SCALING_FACTOR * lastTimeout - : mParams.initialRetransTime; - - // Check if overflow occurred. - if (nextTimeout < lastTimeout) { - nextTimeout = std::numeric_limits<time_type>::max(); - } - - // Cap to maximum allowed, if necessary. - if (mParams.maxRetransTime > TIME_ZERO) { - nextTimeout = std::min(nextTimeout, mParams.maxRetransTime); - } - - // Don't overflow the maximum total duration. - if (mParams.maxRetransDuration > TIME_ZERO) { - nextTimeout = std::min(nextTimeout, mParams.maxRetransDuration - lastTimeout); - } - return nextTimeout; - } - - const Parameters mParams; - counter_type mRetransCount; - time_type mRetransTime; - time_type mTotalRetransDuration; -}; - -} // namespace netdutils -} // namespace android - -#endif /* NETDUTILS_BACKOFFSEQUENCE_H */ diff --git a/libnetdutils/include/netdutils/DumpWriter.h b/libnetdutils/include/netdutils/DumpWriter.h deleted file mode 100644 index a50b5e60..00000000 --- a/libnetdutils/include/netdutils/DumpWriter.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NETDUTILS_DUMPWRITER_H_ -#define NETDUTILS_DUMPWRITER_H_ - -#include <string> - -namespace android { -namespace netdutils { - -class DumpWriter { - public: - DumpWriter(int fd); - - void incIndent(); - void decIndent(); - - void println(const std::string& line); - template <size_t n> - void println(const char line[n]) { - println(std::string(line)); - } - // Hint to the compiler that it should apply printf validation of - // arguments (beginning at position 3) of the format (specified in - // position 2). Note that position 1 is the implicit "this" argument. - void println(const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3))); - void blankline() { println(""); } - - private: - uint8_t mIndentLevel; - int mFd; -}; - -class ScopedIndent { - public: - ScopedIndent() = delete; - ScopedIndent(const ScopedIndent&) = delete; - ScopedIndent(ScopedIndent&&) = delete; - explicit ScopedIndent(DumpWriter& dw) : mDw(dw) { mDw.incIndent(); } - ~ScopedIndent() { mDw.decIndent(); } - ScopedIndent& operator=(const ScopedIndent&) = delete; - ScopedIndent& operator=(ScopedIndent&&) = delete; - - // TODO: consider additional {inc,dec}Indent methods and a counter that - // can be used to unwind all pending increments on exit. - - private: - DumpWriter& mDw; -}; - -} // namespace netdutils -} // namespace android - -#endif // NETDUTILS_DUMPWRITER_H_ diff --git a/libnetdutils/include/netdutils/Fd.h b/libnetdutils/include/netdutils/Fd.h deleted file mode 100644 index 7db40870..00000000 --- a/libnetdutils/include/netdutils/Fd.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NETUTILS_FD_H -#define NETUTILS_FD_H - -#include <ostream> - -#include "netdutils/Status.h" - -namespace android { -namespace netdutils { - -// Strongly typed wrapper for file descriptors with value semantics. -// This class should typically hold unowned file descriptors. -class Fd { - public: - constexpr Fd() = default; - - constexpr Fd(int fd) : mFd(fd) {} - - int get() const { return mFd; } - - bool operator==(const Fd& other) const { return get() == other.get(); } - bool operator!=(const Fd& other) const { return get() != other.get(); } - - private: - int mFd = -1; -}; - -// Return true if fd appears valid (non-negative) -inline bool isWellFormed(const Fd fd) { - return fd.get() >= 0; -} - -std::ostream& operator<<(std::ostream& os, const Fd& fd); - -} // namespace netdutils -} // namespace android - -#endif /* NETUTILS_FD_H */ diff --git a/libnetdutils/include/netdutils/Handle.h b/libnetdutils/include/netdutils/Handle.h deleted file mode 100644 index 82083d41..00000000 --- a/libnetdutils/include/netdutils/Handle.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NETUTILS_HANDLE_H -#define NETUTILS_HANDLE_H - -#include <ostream> - -namespace android { -namespace netdutils { - -// Opaque, strongly typed wrapper for integer-like handles. -// Explicitly avoids implementing arithmetic operations. -// -// This class is intended to avoid common errors when reordering -// arguments to functions, typos and other cases where plain integer -// types would silently cover up the mistake. -// -// usage: -// DEFINE_HANDLE(ProductId, uint64_t); -// DEFINE_HANDLE(ThumbnailHash, uint64_t); -// void foo(ProductId p, ThumbnailHash th) {...} -// -// void test() { -// ProductId p(88); -// ThumbnailHash th1(100), th2(200); -// -// foo(p, th1); <- ok! -// foo(th1, p); <- disallowed! -// th1 += 10; <- disallowed! -// p = th2; <- disallowed! -// assert(th1 != th2); <- ok! -// } -template <typename T, typename TagT> -class Handle { - public: - constexpr Handle() = default; - constexpr Handle(const T& value) : mValue(value) {} - - const T get() const { return mValue; } - - bool operator==(const Handle& that) const { return get() == that.get(); } - bool operator!=(const Handle& that) const { return get() != that.get(); } - - private: - T mValue; -}; - -#define DEFINE_HANDLE(name, type) \ - struct _##name##Tag {}; \ - using name = ::android::netdutils::Handle<type, _##name##Tag>; - -template <typename T, typename TagT> -inline std::ostream& operator<<(std::ostream& os, const Handle<T, TagT>& handle) { - return os << handle.get(); -} - -} // namespace netdutils -} // namespace android - -#endif /* NETUTILS_HANDLE_H */ diff --git a/libnetdutils/include/netdutils/InternetAddresses.h b/libnetdutils/include/netdutils/InternetAddresses.h deleted file mode 100644 index d5cbe2b4..00000000 --- a/libnetdutils/include/netdutils/InternetAddresses.h +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <netdb.h> -#include <netinet/in.h> -#include <stdint.h> -#include <cstring> -#include <limits> -#include <string> - -#include "netdutils/NetworkConstants.h" - -namespace android { -namespace netdutils { - -namespace internal_ { - -// A structure to hold data for dealing with Internet addresses (IPAddress) and -// related types such as IPSockAddr and IPPrefix. -struct compact_ipdata { - uint8_t family{AF_UNSPEC}; - uint8_t cidrlen{0U}; // written and read in host-byte order - in_port_t port{0U}; // written and read in host-byte order - uint32_t scope_id{0U}; - union { - in_addr v4; - in6_addr v6; - } ip{.v6 = IN6ADDR_ANY_INIT}; // written and read in network-byte order - - // Classes that use compact_ipdata and this method should be sure to clear - // (i.e. zero or make uniform) any fields not relevant to the class. - friend bool operator==(const compact_ipdata& a, const compact_ipdata& b) { - if ((a.family != b.family) || (a.cidrlen != b.cidrlen) || (a.port != b.port) || - (a.scope_id != b.scope_id)) { - return false; - } - switch (a.family) { - case AF_UNSPEC: - // After the above checks, two AF_UNSPEC objects can be - // considered equal, for convenience. - return true; - case AF_INET: { - const in_addr v4a = a.ip.v4; - const in_addr v4b = b.ip.v4; - return (v4a.s_addr == v4b.s_addr); - } - case AF_INET6: { - const in6_addr v6a = a.ip.v6; - const in6_addr v6b = b.ip.v6; - return IN6_ARE_ADDR_EQUAL(&v6a, &v6b); - } - } - return false; - } - - // Classes that use compact_ipdata and this method should be sure to clear - // (i.e. zero or make uniform) any fields not relevant to the class. - friend bool operator!=(const compact_ipdata& a, const compact_ipdata& b) { return !(a == b); } - - // Classes that use compact_ipdata and this method should be sure to clear - // (i.e. zero or make uniform) any fields not relevant to the class. - friend bool operator<(const compact_ipdata& a, const compact_ipdata& b) { - if (a.family != b.family) return (a.family < b.family); - switch (a.family) { - case AF_INET: { - const in_addr v4a = a.ip.v4; - const in_addr v4b = b.ip.v4; - if (v4a.s_addr != v4b.s_addr) return (ntohl(v4a.s_addr) < ntohl(v4b.s_addr)); - break; - } - case AF_INET6: { - const in6_addr v6a = a.ip.v6; - const in6_addr v6b = b.ip.v6; - const int cmp = std::memcmp(v6a.s6_addr, v6b.s6_addr, IPV6_ADDR_LEN); - if (cmp != 0) return cmp < 0; - break; - } - } - if (a.cidrlen != b.cidrlen) return (a.cidrlen < b.cidrlen); - if (a.port != b.port) return (a.port < b.port); - return (a.scope_id < b.scope_id); - } -}; - -static_assert(AF_UNSPEC <= std::numeric_limits<uint8_t>::max(), "AF_UNSPEC value too large"); -static_assert(AF_INET <= std::numeric_limits<uint8_t>::max(), "AF_INET value too large"); -static_assert(AF_INET6 <= std::numeric_limits<uint8_t>::max(), "AF_INET6 value too large"); -static_assert(sizeof(compact_ipdata) == 24U, "compact_ipdata unexpectedly large"); - -} // namespace internal_ - -struct AddrinfoDeleter { - void operator()(struct addrinfo* p) const { - if (p != nullptr) { - freeaddrinfo(p); - } - } -}; - -typedef std::unique_ptr<struct addrinfo, struct AddrinfoDeleter> ScopedAddrinfo; - -inline bool usesScopedIds(const in6_addr& ipv6) { - return (IN6_IS_ADDR_LINKLOCAL(&ipv6) || IN6_IS_ADDR_MC_LINKLOCAL(&ipv6)); -} - -class IPPrefix; -class IPSockAddr; - -class IPAddress { - public: - static bool forString(const std::string& repr, IPAddress* ip); - static IPAddress forString(const std::string& repr) { - IPAddress ip; - if (!forString(repr, &ip)) return IPAddress(); - return ip; - } - - IPAddress() = default; - IPAddress(const IPAddress&) = default; - IPAddress(IPAddress&&) = default; - - explicit IPAddress(const in_addr& ipv4) - : mData({AF_INET, IPV4_ADDR_BITS, 0U, 0U, {.v4 = ipv4}}) {} - explicit IPAddress(const in6_addr& ipv6) - : mData({AF_INET6, IPV6_ADDR_BITS, 0U, 0U, {.v6 = ipv6}}) {} - IPAddress(const in6_addr& ipv6, uint32_t scope_id) - : mData({AF_INET6, - IPV6_ADDR_BITS, - 0U, - // Sanity check: scoped_ids only for link-local addresses. - usesScopedIds(ipv6) ? scope_id : 0U, - {.v6 = ipv6}}) {} - IPAddress(const IPAddress& ip, uint32_t scope_id) : IPAddress(ip) { - mData.scope_id = (family() == AF_INET6 && usesScopedIds(mData.ip.v6)) ? scope_id : 0U; - } - - IPAddress& operator=(const IPAddress&) = default; - IPAddress& operator=(IPAddress&&) = default; - - constexpr sa_family_t family() const noexcept { return mData.family; } - constexpr uint32_t scope_id() const noexcept { return mData.scope_id; } - - std::string toString() const noexcept; - - friend std::ostream& operator<<(std::ostream& os, const IPAddress& ip) { - os << ip.toString(); - return os; - } - friend bool operator==(const IPAddress& a, const IPAddress& b) { return (a.mData == b.mData); } - friend bool operator!=(const IPAddress& a, const IPAddress& b) { return (a.mData != b.mData); } - friend bool operator<(const IPAddress& a, const IPAddress& b) { return (a.mData < b.mData); } - friend bool operator>(const IPAddress& a, const IPAddress& b) { return (b.mData < a.mData); } - friend bool operator<=(const IPAddress& a, const IPAddress& b) { return (a < b) || (a == b); } - friend bool operator>=(const IPAddress& a, const IPAddress& b) { return (b < a) || (a == b); } - - private: - friend class IPPrefix; - friend class IPSockAddr; - - explicit IPAddress(const internal_::compact_ipdata& ipdata) : mData(ipdata) { - mData.port = 0U; - switch (mData.family) { - case AF_INET: - mData.cidrlen = IPV4_ADDR_BITS; - mData.scope_id = 0U; - break; - case AF_INET6: - mData.cidrlen = IPV6_ADDR_BITS; - if (usesScopedIds(ipdata.ip.v6)) mData.scope_id = ipdata.scope_id; - break; - default: - mData.cidrlen = 0U; - mData.scope_id = 0U; - break; - } - } - - internal_::compact_ipdata mData{}; -}; - -class IPPrefix { - public: - static bool forString(const std::string& repr, IPPrefix* prefix); - static IPPrefix forString(const std::string& repr) { - IPPrefix prefix; - if (!forString(repr, &prefix)) return IPPrefix(); - return prefix; - } - - IPPrefix() = default; - IPPrefix(const IPPrefix&) = default; - IPPrefix(IPPrefix&&) = default; - - explicit IPPrefix(const IPAddress& ip) : mData(ip.mData) {} - - // Truncate the IP address |ip| at length |length|. Lengths greater than - // the address-family-relevant maximum, along with negative values, are - // interpreted as if the address-family-relevant maximum had been given. - IPPrefix(const IPAddress& ip, int length); - - IPPrefix& operator=(const IPPrefix&) = default; - IPPrefix& operator=(IPPrefix&&) = default; - - constexpr sa_family_t family() const noexcept { return mData.family; } - IPAddress ip() const noexcept { return IPAddress(mData); } - in_addr addr4() const noexcept { return mData.ip.v4; } - in6_addr addr6() const noexcept { return mData.ip.v6; } - constexpr int length() const noexcept { return mData.cidrlen; } - - bool isUninitialized() const noexcept; - std::string toString() const noexcept; - - friend std::ostream& operator<<(std::ostream& os, const IPPrefix& prefix) { - os << prefix.toString(); - return os; - } - friend bool operator==(const IPPrefix& a, const IPPrefix& b) { return (a.mData == b.mData); } - friend bool operator!=(const IPPrefix& a, const IPPrefix& b) { return (a.mData != b.mData); } - friend bool operator<(const IPPrefix& a, const IPPrefix& b) { return (a.mData < b.mData); } - friend bool operator>(const IPPrefix& a, const IPPrefix& b) { return (b.mData < a.mData); } - friend bool operator<=(const IPPrefix& a, const IPPrefix& b) { return (a < b) || (a == b); } - friend bool operator>=(const IPPrefix& a, const IPPrefix& b) { return (b < a) || (a == b); } - - private: - internal_::compact_ipdata mData{}; -}; - -// An Internet socket address. -// -// Cannot represent other types of socket addresses (e.g. UNIX socket address, et cetera). -class IPSockAddr { - public: - // TODO: static forString - - static IPSockAddr toIPSockAddr(const std::string& repr, in_port_t port) { - return IPSockAddr(IPAddress::forString(repr), port); - } - static IPSockAddr toIPSockAddr(const sockaddr& sa) { - switch (sa.sa_family) { - case AF_INET: - return IPSockAddr(*reinterpret_cast<const sockaddr_in*>(&sa)); - case AF_INET6: - return IPSockAddr(*reinterpret_cast<const sockaddr_in6*>(&sa)); - default: - return IPSockAddr(); - } - } - static IPSockAddr toIPSockAddr(const sockaddr_storage& ss) { - return toIPSockAddr(*reinterpret_cast<const sockaddr*>(&ss)); - } - - IPSockAddr() = default; - IPSockAddr(const IPSockAddr&) = default; - IPSockAddr(IPSockAddr&&) = default; - - explicit IPSockAddr(const IPAddress& ip) : mData(ip.mData) {} - IPSockAddr(const IPAddress& ip, in_port_t port) : mData(ip.mData) { mData.port = port; } - explicit IPSockAddr(const sockaddr_in& ipv4sa) - : IPSockAddr(IPAddress(ipv4sa.sin_addr), ntohs(ipv4sa.sin_port)) {} - explicit IPSockAddr(const sockaddr_in6& ipv6sa) - : IPSockAddr(IPAddress(ipv6sa.sin6_addr, ipv6sa.sin6_scope_id), ntohs(ipv6sa.sin6_port)) {} - - IPSockAddr& operator=(const IPSockAddr&) = default; - IPSockAddr& operator=(IPSockAddr&&) = default; - - constexpr sa_family_t family() const noexcept { return mData.family; } - IPAddress ip() const noexcept { return IPAddress(mData); } - constexpr in_port_t port() const noexcept { return mData.port; } - - // Implicit conversion to sockaddr_storage. - operator sockaddr_storage() const noexcept { - sockaddr_storage ss; - ss.ss_family = mData.family; - switch (mData.family) { - case AF_INET: - reinterpret_cast<sockaddr_in*>(&ss)->sin_addr = mData.ip.v4; - reinterpret_cast<sockaddr_in*>(&ss)->sin_port = htons(mData.port); - break; - case AF_INET6: - reinterpret_cast<sockaddr_in6*>(&ss)->sin6_addr = mData.ip.v6; - reinterpret_cast<sockaddr_in6*>(&ss)->sin6_port = htons(mData.port); - reinterpret_cast<sockaddr_in6*>(&ss)->sin6_scope_id = mData.scope_id; - break; - } - return ss; - } - - std::string toString() const noexcept; - - friend std::ostream& operator<<(std::ostream& os, const IPSockAddr& prefix) { - os << prefix.toString(); - return os; - } - friend bool operator==(const IPSockAddr& a, const IPSockAddr& b) { - return (a.mData == b.mData); - } - friend bool operator!=(const IPSockAddr& a, const IPSockAddr& b) { - return (a.mData != b.mData); - } - friend bool operator<(const IPSockAddr& a, const IPSockAddr& b) { return (a.mData < b.mData); } - friend bool operator>(const IPSockAddr& a, const IPSockAddr& b) { return (b.mData < a.mData); } - friend bool operator<=(const IPSockAddr& a, const IPSockAddr& b) { return (a < b) || (a == b); } - friend bool operator>=(const IPSockAddr& a, const IPSockAddr& b) { return (b < a) || (a == b); } - - private: - internal_::compact_ipdata mData{}; -}; - -} // namespace netdutils -} // namespace android diff --git a/libnetdutils/include/netdutils/Log.h b/libnetdutils/include/netdutils/Log.h deleted file mode 100644 index 77ae6494..00000000 --- a/libnetdutils/include/netdutils/Log.h +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NETUTILS_LOG_H -#define NETUTILS_LOG_H - -#include <chrono> -#include <deque> -#include <shared_mutex> -#include <string> -#include <type_traits> -#include <vector> - -#include <android-base/stringprintf.h> -#include <android-base/thread_annotations.h> - -#include <netdutils/Status.h> - -namespace android { -namespace netdutils { - -class LogEntry { - public: - LogEntry() = default; - LogEntry(const LogEntry&) = default; - LogEntry(LogEntry&&) = default; - ~LogEntry() = default; - LogEntry& operator=(const LogEntry&) = default; - LogEntry& operator=(LogEntry&&) = default; - - std::string toString() const; - - /// - // Helper methods that make it easy to build up a LogEntry message. - // If performance becomes a factor the implementations could be inlined. - /// - LogEntry& message(const std::string& message); - - // For calling with __FUNCTION__. - LogEntry& function(const std::string& function_name); - // For calling with __PRETTY_FUNCTION__. - LogEntry& prettyFunction(const std::string& pretty_function); - - // Convenience methods for each of the common types of function arguments. - LogEntry& arg(const std::string& val); - // Intended for binary buffers, formats as hex - LogEntry& arg(const std::vector<uint8_t>& val); - LogEntry& arg(const std::vector<int32_t>& val); - LogEntry& arg(const std::vector<std::string>& val); - template <typename IntT, typename = std::enable_if_t<std::is_arithmetic_v<IntT>>> - LogEntry& arg(IntT val) { - mArgs.push_back(std::to_string(val)); - return *this; - } - // Not using a plain overload here to avoid the implicit conversion from - // any pointer to bool, which causes string literals to print as 'true'. - template <> - LogEntry& arg<>(bool val); - - template <typename... Args> - LogEntry& args(const Args&... a) { - // Cleverness ahead: we throw away the initializer_list filled with - // zeroes, all we care about is calling arg() for each argument. - (void) std::initializer_list<int>{(arg(a), 0)...}; - return *this; - } - - // Some things can return more than one value, or have multiple output - // parameters, so each of these adds to the mReturns vector. - LogEntry& returns(const std::string& rval); - LogEntry& returns(const Status& status); - LogEntry& returns(bool rval); - template <class T> - LogEntry& returns(T val) { - mReturns.push_back(std::to_string(val)); - return *this; - } - - LogEntry& withUid(uid_t uid); - - // Append the duration computed since the creation of this instance. - LogEntry& withAutomaticDuration(); - // Append the string-ified duration computed by some other means. - LogEntry& withDuration(const std::string& duration); - - private: - std::chrono::steady_clock::time_point mStart = std::chrono::steady_clock::now(); - std::string mMsg{}; - std::string mFunc{}; - std::vector<std::string> mArgs{}; - std::vector<std::string> mReturns{}; - std::string mUid{}; - std::string mDuration{}; -}; - -class Log { - public: - Log() = delete; - Log(const std::string& tag) : Log(tag, MAX_ENTRIES) {} - Log(const std::string& tag, size_t maxEntries) : mTag(tag), mMaxEntries(maxEntries) {} - Log(const Log&) = delete; - Log(Log&&) = delete; - ~Log(); - Log& operator=(const Log&) = delete; - Log& operator=(Log&&) = delete; - - LogEntry newEntry() const { return LogEntry(); } - - // Record a log entry in internal storage only. - void log(const std::string& entry) { record(Level::LOG, entry); } - template <size_t n> - void log(const char entry[n]) { log(std::string(entry)); } - void log(const LogEntry& entry) { log(entry.toString()); } - void log(const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3))) { - using ::android::base::StringAppendV; - std::string result; - va_list ap; - va_start(ap, fmt); - StringAppendV(&result, fmt, ap); - va_end(ap); - log(result); - } - - // Record a log entry in internal storage and to ALOGI as well. - void info(const std::string& entry) { record(Level::INFO, entry); } - template <size_t n> - void info(const char entry[n]) { info(std::string(entry)); } - void info(const LogEntry& entry) { info(entry.toString()); } - void info(const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3))) { - using ::android::base::StringAppendV; - std::string result; - va_list ap; - va_start(ap, fmt); - StringAppendV(&result, fmt, ap); - va_end(ap); - info(result); - } - - // Record a log entry in internal storage and to ALOGW as well. - void warn(const std::string& entry) { record(Level::WARN, entry); } - template <size_t n> - void warn(const char entry[n]) { warn(std::string(entry)); } - void warn(const LogEntry& entry) { warn(entry.toString()); } - void warn(const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3))) { - using ::android::base::StringAppendV; - std::string result; - va_list ap; - va_start(ap, fmt); - StringAppendV(&result, fmt, ap); - va_end(ap); - warn(result); - } - - // Record a log entry in internal storage and to ALOGE as well. - void error(const std::string& entry) { record(Level::ERROR, entry); } - template <size_t n> - void error(const char entry[n]) { error(std::string(entry)); } - void error(const LogEntry& entry) { error(entry.toString()); } - void error(const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3))) { - using ::android::base::StringAppendV; - std::string result; - va_list ap; - va_start(ap, fmt); - StringAppendV(&result, fmt, ap); - va_end(ap); - error(result); - } - - // Iterates over every entry in the log in chronological order. Operates - // on a copy of the log entries, and so perEntryFn may itself call one of - // the logging functions if needed. - void forEachEntry(const std::function<void(const std::string&)>& perEntryFn) const; - - private: - static constexpr const size_t MAX_ENTRIES = 750U; - const std::string mTag; - const size_t mMaxEntries; - - // The LOG level adds an entry to mEntries but does not output the message - // to the system log. All other levels append to mEntries and output to the - // the system log. - enum class Level { - LOG, - INFO, - WARN, - ERROR, - }; - - void record(Level lvl, const std::string& entry); - - mutable std::shared_mutex mLock; - std::deque<const std::string> mEntries; // GUARDED_BY(mLock), when supported -}; - -} // namespace netdutils -} // namespace android - -#endif /* NETUTILS_LOG_H */ diff --git a/libnetdutils/include/netdutils/Math.h b/libnetdutils/include/netdutils/Math.h deleted file mode 100644 index c41fbf58..00000000 --- a/libnetdutils/include/netdutils/Math.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NETUTILS_MATH_H -#define NETUTILS_MATH_H - -#include <algorithm> -#include <cstdint> - -namespace android { -namespace netdutils { - -template <class T> -inline constexpr const T mask(const int shift) { - return (1 << shift) - 1; -} - -// Align x up to the nearest integer multiple of 2^shift -template <class T> -inline constexpr const T align(const T& x, const int shift) { - return (x + mask<T>(shift)) & ~mask<T>(shift); -} - -} // namespace netdutils -} // namespace android - -#endif /* NETUTILS_MATH_H */ diff --git a/libnetdutils/include/netdutils/MemBlock.h b/libnetdutils/include/netdutils/MemBlock.h deleted file mode 100644 index fd4d612d..00000000 --- a/libnetdutils/include/netdutils/MemBlock.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NETUTILS_MEMBLOCK_H -#define NETUTILS_MEMBLOCK_H - -#include <memory> -#include "netdutils/Slice.h" - -namespace android { -namespace netdutils { - -// A class to encapsulate self-deleting byte arrays while preserving access -// to the underlying length (without the length being part of the type, e.g. -// std::array<>). By design, the only interface to the underlying bytes is -// via Slice, to encourage safer memory access usage. -// -// No thread-safety guarantees whatsoever. -class MemBlock { - public: - MemBlock() : MemBlock(0U) {} - explicit MemBlock(size_t len) - : mData((len > 0U) ? new uint8_t[len]{} : nullptr), - mLen(len) {} - // Allocate memory of size src.size() and copy src into this MemBlock. - explicit MemBlock(Slice src) : MemBlock(src.size()) { - copy(get(), src); - } - - // No copy construction or assignment. - MemBlock(const MemBlock&) = delete; - MemBlock& operator=(const MemBlock&) = delete; - - // Move construction and assignment are okay. - MemBlock(MemBlock&&) = default; - MemBlock& operator=(MemBlock&&) = default; - - // Even though this method is const, the memory wrapped by the - // returned Slice is mutable. - Slice get() const noexcept { return Slice(mData.get(), mLen); } - - // Implicit cast to Slice. - // NOLINTNEXTLINE(google-explicit-constructor) - operator const Slice() const noexcept { return get(); } - - private: - std::unique_ptr<uint8_t[]> mData; - size_t mLen; -}; - -} // namespace netdutils -} // namespace android - -#endif /* NETUTILS_MEMBLOCK_H */ diff --git a/libnetdutils/include/netdutils/Misc.h b/libnetdutils/include/netdutils/Misc.h deleted file mode 100644 index d344f81f..00000000 --- a/libnetdutils/include/netdutils/Misc.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NETUTILS_MISC_H -#define NETUTILS_MISC_H - -#include <map> - -namespace android { -namespace netdutils { - -// Lookup key in map, returing a default value if key is not found -template <typename U, typename V> -inline const V& findWithDefault(const std::map<U, V>& map, const U& key, const V& dflt) { - auto it = map.find(key); - return (it == map.end()) ? dflt : it->second; -} - -// Movable, copiable, scoped lambda (or std::function) runner. Useful -// for running arbitrary cleanup or logging code when exiting a scope. -// -// Compare to defer in golang. -template <typename FnT> -class Cleanup { - public: - Cleanup() = delete; - explicit Cleanup(FnT fn) : mFn(fn) {} - ~Cleanup() { if (!mReleased) mFn(); } - - void release() { mReleased = true; } - - private: - bool mReleased{false}; - FnT mFn; -}; - -// Helper to make a new Cleanup. Avoids complex or impossible syntax -// when wrapping lambdas. -// -// Usage: -// auto cleanup = makeCleanup([](){ your_code_here; }); -template <typename FnT> -Cleanup<FnT> makeCleanup(FnT fn) { - return Cleanup<FnT>(fn); -} - -} // namespace netdutils -} // namespace android - -#endif /* NETUTILS_MISC_H */ diff --git a/libnetdutils/include/netdutils/MockSyscalls.h b/libnetdutils/include/netdutils/MockSyscalls.h deleted file mode 100644 index f57b55ca..00000000 --- a/libnetdutils/include/netdutils/MockSyscalls.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NETUTILS_MOCK_SYSCALLS_H -#define NETUTILS_MOCK_SYSCALLS_H - -#include <atomic> -#include <cassert> -#include <memory> - -#include <gmock/gmock.h> -#include <gtest/gtest.h> - -#include "netdutils/Syscalls.h" - -namespace android { -namespace netdutils { - -class MockSyscalls : public Syscalls { - public: - virtual ~MockSyscalls() = default; - // Use Return(ByMove(...)) to deal with movable return types. - MOCK_CONST_METHOD3(open, - StatusOr<UniqueFd>(const std::string& pathname, int flags, mode_t mode)); - MOCK_CONST_METHOD3(socket, StatusOr<UniqueFd>(int domain, int type, int protocol)); - MOCK_CONST_METHOD3(getsockname, Status(Fd sock, sockaddr* addr, socklen_t* addrlen)); - MOCK_CONST_METHOD5(getsockopt, Status(Fd sock, int level, int optname, void* optval, - socklen_t *optlen)); - MOCK_CONST_METHOD5(setsockopt, Status(Fd sock, int level, int optname, const void* optval, - socklen_t optlen)); - - MOCK_CONST_METHOD3(bind, Status(Fd sock, const sockaddr* addr, socklen_t addrlen)); - MOCK_CONST_METHOD3(connect, Status(Fd sock, const sockaddr* addr, socklen_t addrlen)); - MOCK_CONST_METHOD3(ioctl, StatusOr<ifreq>(Fd sock, unsigned long request, ifreq* ifr)); - - // Use Return(ByMove(...)) to deal with movable return types. - MOCK_CONST_METHOD2(eventfd, StatusOr<UniqueFd>(unsigned int initval, int flags)); - MOCK_CONST_METHOD3(ppoll, StatusOr<int>(pollfd* fds, nfds_t nfds, double timeout)); - - MOCK_CONST_METHOD2(writev, StatusOr<size_t>(Fd fd, const std::vector<iovec>& iov)); - MOCK_CONST_METHOD2(write, StatusOr<size_t>(Fd fd, const Slice buf)); - MOCK_CONST_METHOD2(read, StatusOr<Slice>(Fd fd, const Slice buf)); - MOCK_CONST_METHOD5(sendto, StatusOr<size_t>(Fd sock, const Slice buf, int flags, - const sockaddr* dst, socklen_t dstlen)); - MOCK_CONST_METHOD5(recvfrom, StatusOr<Slice>(Fd sock, const Slice dst, int flags, sockaddr* src, - socklen_t* srclen)); - MOCK_CONST_METHOD2(shutdown, Status(Fd fd, int how)); - MOCK_CONST_METHOD1(close, Status(Fd fd)); - - MOCK_CONST_METHOD2(fopen, - StatusOr<UniqueFile>(const std::string& path, const std::string& mode)); - MOCK_CONST_METHOD3(vfprintf, StatusOr<int>(FILE* file, const char* format, va_list ap)); - MOCK_CONST_METHOD3(vfscanf, StatusOr<int>(FILE* file, const char* format, va_list ap)); - MOCK_CONST_METHOD1(fclose, Status(FILE* file)); - MOCK_CONST_METHOD0(fork, StatusOr<pid_t>()); -}; - -// For the lifetime of this mock, replace the contents of sSyscalls -// with a pointer to this mock. Behavior is undefined if multiple -// ScopedMockSyscalls instances exist concurrently. -class ScopedMockSyscalls : public MockSyscalls { - public: - ScopedMockSyscalls() : mOld(sSyscalls.swap(*this)) { assert((mRefcount++) == 1); } - virtual ~ScopedMockSyscalls() { - sSyscalls.swap(mOld); - assert((mRefcount--) == 0); - } - - private: - std::atomic<int> mRefcount{0}; - Syscalls& mOld; -}; - -} // namespace netdutils -} // namespace android - -#endif /* NETUTILS_MOCK_SYSCALLS_H */ diff --git a/libnetdutils/include/netdutils/Netfilter.h b/libnetdutils/include/netdutils/Netfilter.h deleted file mode 100644 index 22736f19..00000000 --- a/libnetdutils/include/netdutils/Netfilter.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NETUTILS_NETFILTER_H -#define NETUTILS_NETFILTER_H - -#include <ostream> - -#include <linux/netfilter.h> -#include <linux/netfilter/nfnetlink.h> -#include <linux/netlink.h> - -std::ostream& operator<<(std::ostream& os, const nfgenmsg& msg); - -#endif /* NETUTILS_NETFILTER_H */ diff --git a/libnetdutils/include/netdutils/Netlink.h b/libnetdutils/include/netdutils/Netlink.h deleted file mode 100644 index ee5183ab..00000000 --- a/libnetdutils/include/netdutils/Netlink.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NETUTILS_NETLINK_H -#define NETUTILS_NETLINK_H - -#include <functional> -#include <ostream> -#include <linux/netlink.h> - -#include "netdutils/Slice.h" - -namespace android { -namespace netdutils { - -// Invoke onMsg once for each netlink message in buf. onMsg will be -// invoked with an aligned and deserialized header along with a Slice -// containing the message payload. -// -// Assume that the first message begins at offset zero within buf. -void forEachNetlinkMessage(const Slice buf, - const std::function<void(const nlmsghdr&, const Slice)>& onMsg); - -// Invoke onAttr once for each netlink attribute in buf. onAttr will be -// invoked with an aligned and deserialized header along with a Slice -// containing the attribute payload. -// -// Assume that the first attribute begins at offset zero within buf. -void forEachNetlinkAttribute(const Slice buf, - const std::function<void(const nlattr&, const Slice)>& onAttr); - -} // namespace netdutils -} // namespace android - -bool operator==(const sockaddr_nl& lhs, const sockaddr_nl& rhs); -bool operator!=(const sockaddr_nl& lhs, const sockaddr_nl& rhs); - -std::ostream& operator<<(std::ostream& os, const nlmsghdr& hdr); -std::ostream& operator<<(std::ostream& os, const nlattr& attr); -std::ostream& operator<<(std::ostream& os, const sockaddr_nl& addr); - -#endif /* NETUTILS_NETLINK_H */ diff --git a/libnetdutils/include/netdutils/NetworkConstants.h b/libnetdutils/include/netdutils/NetworkConstants.h deleted file mode 100644 index dead9a17..00000000 --- a/libnetdutils/include/netdutils/NetworkConstants.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -namespace android { -namespace netdutils { - -// See also NetworkConstants.java in frameworks/base. -constexpr int IPV4_ADDR_LEN = 4; -constexpr int IPV4_ADDR_BITS = 32; -constexpr int IPV6_ADDR_LEN = 16; -constexpr int IPV6_ADDR_BITS = 128; - -// Referred from SHA256_DIGEST_LENGTH in boringssl -constexpr size_t SHA256_SIZE = 32; - -} // namespace netdutils -} // namespace android diff --git a/libnetdutils/include/netdutils/ResponseCode.h b/libnetdutils/include/netdutils/ResponseCode.h deleted file mode 100644 index c170684c..00000000 --- a/libnetdutils/include/netdutils/ResponseCode.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NETDUTILS_RESPONSECODE_H -#define NETDUTILS_RESPONSECODE_H - -namespace android { -namespace netdutils { - -class ResponseCode { - // Keep in sync with - // frameworks/base/services/java/com/android/server/NetworkManagementService.java - public: - // 100 series - Requestion action was initiated; expect another reply - // before proceeding with a new command. - // clang-format off - static constexpr int ActionInitiated = 100; - static constexpr int InterfaceListResult = 110; - static constexpr int TetherInterfaceListResult = 111; - static constexpr int TetherDnsFwdTgtListResult = 112; - static constexpr int TtyListResult = 113; - static constexpr int TetheringStatsListResult = 114; - static constexpr int TetherDnsFwdNetIdResult = 115; - - // 200 series - Requested action has been successfully completed - static constexpr int CommandOkay = 200; - static constexpr int TetherStatusResult = 210; - static constexpr int IpFwdStatusResult = 211; - static constexpr int InterfaceGetCfgResult = 213; - // Formerly: int SoftapStatusResult = 214; - static constexpr int UsbRNDISStatusResult = 215; - static constexpr int InterfaceRxCounterResult = 216; - static constexpr int InterfaceTxCounterResult = 217; - static constexpr int InterfaceRxThrottleResult = 218; - static constexpr int InterfaceTxThrottleResult = 219; - static constexpr int QuotaCounterResult = 220; - static constexpr int TetheringStatsResult = 221; - // NOTE: keep synced with bionic/libc/dns/net/gethnamaddr.c - static constexpr int DnsProxyQueryResult = 222; - static constexpr int ClatdStatusResult = 223; - - // 400 series - The command was accepted but the requested action - // did not take place. - static constexpr int OperationFailed = 400; - static constexpr int DnsProxyOperationFailed = 401; - static constexpr int ServiceStartFailed = 402; - static constexpr int ServiceStopFailed = 403; - - // 500 series - The command was not accepted and the requested - // action did not take place. - static constexpr int CommandSyntaxError = 500; - static constexpr int CommandParameterError = 501; - - // 600 series - Unsolicited broadcasts - static constexpr int InterfaceChange = 600; - static constexpr int BandwidthControl = 601; - static constexpr int ServiceDiscoveryFailed = 602; - static constexpr int ServiceDiscoveryServiceAdded = 603; - static constexpr int ServiceDiscoveryServiceRemoved = 604; - static constexpr int ServiceRegistrationFailed = 605; - static constexpr int ServiceRegistrationSucceeded = 606; - static constexpr int ServiceResolveFailed = 607; - static constexpr int ServiceResolveSuccess = 608; - static constexpr int ServiceSetHostnameFailed = 609; - static constexpr int ServiceSetHostnameSuccess = 610; - static constexpr int ServiceGetAddrInfoFailed = 611; - static constexpr int ServiceGetAddrInfoSuccess = 612; - static constexpr int InterfaceClassActivity = 613; - static constexpr int InterfaceAddressChange = 614; - static constexpr int InterfaceDnsInfo = 615; - static constexpr int RouteChange = 616; - static constexpr int StrictCleartext = 617; - // clang-format on -}; - -} // namespace netdutils -} // namespace android - -#endif // NETDUTILS_RESPONSECODE_H diff --git a/libnetdutils/include/netdutils/Slice.h b/libnetdutils/include/netdutils/Slice.h deleted file mode 100644 index 717fbd1f..00000000 --- a/libnetdutils/include/netdutils/Slice.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NETUTILS_SLICE_H -#define NETUTILS_SLICE_H - -#include <algorithm> -#include <array> -#include <cstring> -#include <ostream> -#include <tuple> -#include <vector> - -namespace android { -namespace netdutils { - -// Immutable wrapper for a linear region of unowned bytes. -// Slice represents memory as a half-closed interval [base, limit). -// -// Note that without manually invoking the Slice() constructor, it is -// impossible to increase the size of a slice. This guarantees that -// applications that properly use the slice API will never access -// memory outside of a slice. -// -// Note that const Slice still wraps mutable memory, however copy -// assignment and move assignment to slice are disabled. -class Slice { - public: - Slice() = default; - - // Create a slice beginning at base and continuing to but not including limit - Slice(void* base, void* limit) : mBase(toUint8(base)), mLimit(toUint8(limit)) {} - - // Create a slice beginning at base and continuing for size bytes - Slice(void* base, size_t size) : Slice(base, toUint8(base) + size) {} - - // Return the address of the first byte in this slice - uint8_t* base() const { return mBase; } - - // Return the address of the first byte following this slice - uint8_t* limit() const { return mLimit; } - - // Return the size of this slice in bytes - size_t size() const { return limit() - base(); } - - // Return true if size() == 0 - bool empty() const { return base() == limit(); } - - private: - static uint8_t* toUint8(void* ptr) { return reinterpret_cast<uint8_t*>(ptr); } - - uint8_t* mBase = nullptr; - uint8_t* mLimit = nullptr; -}; - -// Return slice representation of ref which must be a POD type -template <typename T> -inline const Slice makeSlice(const T& ref) { - static_assert(std::is_pod<T>::value, "value must be a POD type"); - static_assert(!std::is_pointer<T>::value, "value must not be a pointer type"); - return {const_cast<T*>(&ref), sizeof(ref)}; -} - -// Return slice representation of string data() -inline const Slice makeSlice(const std::string& s) { - using ValueT = std::string::value_type; - return {const_cast<ValueT*>(s.data()), s.size() * sizeof(ValueT)}; -} - -// Return slice representation of vector data() -template <typename T> -inline const Slice makeSlice(const std::vector<T>& v) { - return {const_cast<T*>(v.data()), v.size() * sizeof(T)}; -} - -// Return slice representation of array data() -template <typename U, size_t V> -inline const Slice makeSlice(const std::array<U, V>& a) { - return {const_cast<U*>(a.data()), a.size() * sizeof(U)}; -} - -// Return prefix and suffix of Slice s ending and starting at position cut -inline std::pair<const Slice, const Slice> split(const Slice s, size_t cut) { - const size_t tmp = std::min(cut, s.size()); - return {{s.base(), s.base() + tmp}, {s.base() + tmp, s.limit()}}; -} - -// Return prefix of Slice s ending at position cut -inline const Slice take(const Slice s, size_t cut) { - return std::get<0>(split(s, cut)); -} - -// Return suffix of Slice s starting at position cut -inline const Slice drop(const Slice s, size_t cut) { - return std::get<1>(split(s, cut)); -} - -// Copy from src into dst. Bytes copied is the lesser of dst.size() and src.size() -inline size_t copy(const Slice dst, const Slice src) { - const auto min = std::min(dst.size(), src.size()); - memcpy(dst.base(), src.base(), min); - return min; -} - -// Base case for variadic extract below -template <typename Head> -inline size_t extract(const Slice src, Head& head) { - return copy(makeSlice(head), src); -} - -// Copy from src into one or more pointers to POD data. If src.size() -// is less than the sum of all data pointers a suffix of data will be -// left unmodified. Return the number of bytes copied. -template <typename Head, typename... Tail> -inline size_t extract(const Slice src, Head& head, Tail&... tail) { - const auto extracted = extract(src, head); - return extracted + extract(drop(src, extracted), tail...); -} - -// Return a string containing a copy of the contents of s -std::string toString(const Slice s); - -// Return a string containing a hexadecimal representation of the contents of s. -// This function inserts a newline into its output every wrap bytes. -std::string toHex(const Slice s, int wrap = INT_MAX); - -inline bool operator==(const Slice& lhs, const Slice& rhs) { - return (lhs.base() == rhs.base()) && (lhs.limit() == rhs.limit()); -} - -inline bool operator!=(const Slice& lhs, const Slice& rhs) { - return !(lhs == rhs); -} - -std::ostream& operator<<(std::ostream& os, const Slice& slice); - -// Return suffix of Slice s starting at the first match of byte c. If no matched -// byte, return an empty Slice. -inline const Slice findFirstMatching(const Slice s, uint8_t c) { - uint8_t* match = (uint8_t*)memchr(s.base(), c, s.size()); - if (!match) return Slice(); - return drop(s, match - s.base()); -} - -} // namespace netdutils -} // namespace android - -#endif /* NETUTILS_SLICE_H */ diff --git a/libnetdutils/include/netdutils/Socket.h b/libnetdutils/include/netdutils/Socket.h deleted file mode 100644 index e5aaab9c..00000000 --- a/libnetdutils/include/netdutils/Socket.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NETDUTILS_SOCKET_H -#define NETDUTILS_SOCKET_H - -#include <netinet/in.h> -#include <sys/socket.h> -#include <string> - -#include "netdutils/StatusOr.h" - -namespace android { -namespace netdutils { - -inline sockaddr* asSockaddrPtr(void* addr) { - return reinterpret_cast<sockaddr*>(addr); -} - -inline const sockaddr* asSockaddrPtr(const void* addr) { - return reinterpret_cast<const sockaddr*>(addr); -} - -// Return a string representation of addr or Status if there was a -// failure during conversion. -StatusOr<std::string> toString(const in6_addr& addr); - -} // namespace netdutils -} // namespace android - -#endif /* NETDUTILS_SOCKET_H */ diff --git a/libnetdutils/include/netdutils/SocketOption.h b/libnetdutils/include/netdutils/SocketOption.h deleted file mode 100644 index 3b0aab75..00000000 --- a/libnetdutils/include/netdutils/SocketOption.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NETDUTILS_SOCKETOPTION_H -#define NETDUTILS_SOCKETOPTION_H - -#include <netinet/in.h> -#include <sys/socket.h> -#include <string> - -#include "netdutils/Fd.h" -#include "netdutils/Status.h" - -namespace android { -namespace netdutils { - -// Turn on simple "boolean" socket options. -// -// This is simple wrapper for options that are enabled via code of the form: -// -// int on = 1; -// setsockopt(..., &on, sizeof(on)); -Status enableSockopt(Fd sock, int level, int optname); - -// Turn on TCP keepalives, and set keepalive parameters for this socket. -// -// A parameter value of zero does not set that parameter. -// -// Typical system defaults are: -// -// idleTime (in seconds) -// $ cat /proc/sys/net/ipv4/tcp_keepalive_time -// 7200 -// -// numProbes -// $ cat /proc/sys/net/ipv4/tcp_keepalive_probes -// 9 -// -// probeInterval (in seconds) -// $ cat /proc/sys/net/ipv4/tcp_keepalive_intvl -// 75 -Status enableTcpKeepAlives(Fd sock, unsigned idleTime, unsigned numProbes, unsigned probeInterval); - -} // namespace netdutils -} // namespace android - -#endif /* NETDUTILS_SOCKETOPTION_H */ diff --git a/libnetdutils/include/netdutils/Status.h b/libnetdutils/include/netdutils/Status.h deleted file mode 100644 index bc347d5e..00000000 --- a/libnetdutils/include/netdutils/Status.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NETUTILS_STATUS_H -#define NETUTILS_STATUS_H - -#include <cassert> -#include <limits> -#include <ostream> - -#include <android-base/result.h> - -namespace android { -namespace netdutils { - -// Simple status implementation suitable for use on the stack in low -// or moderate performance code. This can definitely be improved but -// for now short string optimization is expected to keep the common -// success case fast. -// -// Status is implicitly movable via the default noexcept move constructor -// and noexcept move-assignment operator. -class [[nodiscard]] Status { - public: - Status() = default; - explicit Status(int code) : mCode(code) {} - - // Constructs an error Status, |code| must be non-zero. - Status(int code, std::string msg) : mCode(code), mMsg(std::move(msg)) { assert(!ok()); } - - Status(android::base::Result<void> result) - : mCode(result.ok() ? 0 : result.error().code()), - mMsg(result.ok() ? "" : result.error().message()) {} - - int code() const { return mCode; } - - bool ok() const { return code() == 0; } - - const std::string& msg() const { return mMsg; } - - // Explicitly ignores the Status without triggering [[nodiscard]] errors. - void ignoreError() const {} - - bool operator==(const Status& other) const { return code() == other.code(); } - bool operator!=(const Status& other) const { return !(*this == other); } - - private: - int mCode = 0; - std::string mMsg; -}; - -namespace status { - -const Status ok{0}; -// EOF is not part of errno space, we'll place it far above the -// highest existing value. -const Status eof{0x10001, "end of file"}; -const Status undefined{std::numeric_limits<int>::max(), "undefined"}; - -} // namespace status - -// Return true if status is "OK". This is sometimes preferable to -// status.ok() when we want to check the state of Status-like objects -// that implicitly cast to Status. -inline bool isOk(const Status& status) { - return status.ok(); -} - -// For use only in tests. Used for both Status and Status-like objects. See also isOk(). -#define EXPECT_OK(status) EXPECT_TRUE(isOk(status)) -#define ASSERT_OK(status) ASSERT_TRUE(isOk(status)) - -// Documents that status is expected to be ok. This function may log -// (or assert when running in debug mode) if status has an unexpected value. -inline void expectOk(const Status& /*status*/) { - // TODO: put something here, for now this function serves solely as documentation. -} - -// Convert POSIX errno to a Status object. -// If Status is extended to have more features, this mapping may -// become more complex. -Status statusFromErrno(int err, const std::string& msg); - -// Helper that checks Status-like object (notably StatusOr) against a -// value in the errno space. -bool equalToErrno(const Status& status, int err); - -// Helper that converts Status-like object (notably StatusOr) to a -// message. -std::string toString(const Status& status); - -std::ostream& operator<<(std::ostream& os, const Status& s); - -// Evaluate 'stmt' to a Status object and if it results in an error, return that -// error. Use 'tmp' as a variable name to avoid shadowing any variables named -// tmp. -#define RETURN_IF_NOT_OK_IMPL(tmp, stmt) \ - do { \ - ::android::netdutils::Status tmp = (stmt); \ - if (!isOk(tmp)) { \ - return tmp; \ - } \ - } while (false) - -// Create a unique variable name to avoid shadowing local variables. -#define RETURN_IF_NOT_OK_CONCAT(line, stmt) RETURN_IF_NOT_OK_IMPL(__CONCAT(_status_, line), stmt) - -// Macro to allow exception-like handling of error return values. -// -// If the evaluation of stmt results in an error, return that error -// from current function. -// -// Example usage: -// Status bar() { ... } -// -// RETURN_IF_NOT_OK(status); -// RETURN_IF_NOT_OK(bar()); -#define RETURN_IF_NOT_OK(stmt) RETURN_IF_NOT_OK_CONCAT(__LINE__, stmt) - -} // namespace netdutils -} // namespace android - -#endif /* NETUTILS_STATUS_H */ diff --git a/libnetdutils/include/netdutils/StatusOr.h b/libnetdutils/include/netdutils/StatusOr.h deleted file mode 100644 index c7aa4e4a..00000000 --- a/libnetdutils/include/netdutils/StatusOr.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NETUTILS_STATUSOR_H -#define NETUTILS_STATUSOR_H - -#include <cassert> -#include "netdutils/Status.h" - -namespace android { -namespace netdutils { - -// Wrapper around a combination of Status and application value type. -// T may be any copyable or movable type. -template <typename T> -class [[nodiscard]] StatusOr { - public: - // Constructs a new StatusOr with status::undefined status. - // This is marked 'explicit' to try to catch cases like 'return {};', - // where people think StatusOr<std::vector<int>> will be initialized - // with an empty vector, instead of a status::undefined. - explicit StatusOr() = default; - - // Implicit copy constructor and construction from T. - // NOLINTNEXTLINE(google-explicit-constructor) - StatusOr(Status status) : mStatus(std::move(status)) { assert(!isOk(mStatus)); } - - // Implicit construction from T. It is convenient and sensible to be able - // to do 'return T()' when the return type is StatusOr<T>. - // NOLINTNEXTLINE(google-explicit-constructor) - StatusOr(const T& value) : mStatus(status::ok), mValue(value) {} - // NOLINTNEXTLINE(google-explicit-constructor) - StatusOr(T&& value) : mStatus(status::ok), mValue(std::move(value)) {} - - // Move constructor ok (if T supports move) - StatusOr(StatusOr&&) noexcept = default; - // Move assignment ok (if T supports move) - StatusOr& operator=(StatusOr&&) noexcept = default; - // Copy constructor ok (if T supports copy) - StatusOr(const StatusOr&) = default; - // Copy assignment ok (if T supports copy) - StatusOr& operator=(const StatusOr&) = default; - - // Returns a const reference to wrapped type. - // It is an error to call value() when !isOk(status()) - const T& value() const & { return mValue; } - const T&& value() const && { return mValue; } - - // Returns an rvalue reference to wrapped type - // It is an error to call value() when !isOk(status()) - // - // If T is expensive to copy but supports efficient move, it can be moved - // out of a StatusOr as follows: - // T value = std::move(statusor).value(); - T& value() & { return mValue; } - T&& value() && { return mValue; } - - // Returns the Status object assigned at construction time. - const Status status() const { return mStatus; } - - // Explicitly ignores the Status without triggering [[nodiscard]] errors. - void ignoreError() const {} - - // Implicit cast to Status. - // NOLINTNEXTLINE(google-explicit-constructor) - operator Status() const { return status(); } - - private: - Status mStatus = status::undefined; - T mValue; -}; - -template <typename T> -inline std::ostream& operator<<(std::ostream& os, const StatusOr<T>& s) { - return os << "StatusOr[status: " << s.status() << "]"; -} - -#define ASSIGN_OR_RETURN_IMPL(tmp, lhs, stmt) \ - auto tmp = (stmt); \ - RETURN_IF_NOT_OK(tmp); \ - lhs = std::move(tmp.value()); - -#define ASSIGN_OR_RETURN_CONCAT(line, lhs, stmt) \ - ASSIGN_OR_RETURN_IMPL(__CONCAT(_status_or_, line), lhs, stmt) - -// Macro to allow exception-like handling of error return values. -// -// If the evaluation of stmt results in an error, return that error -// from the current function. Otherwise, assign the result to lhs. -// -// This macro supports both move and copy assignment operators. lhs -// may be either a new local variable or an existing non-const -// variable accessible in the current scope. -// -// Example usage: -// StatusOr<MyType> foo() { ... } -// -// ASSIGN_OR_RETURN(auto myVar, foo()); -// ASSIGN_OR_RETURN(myExistingVar, foo()); -// ASSIGN_OR_RETURN(myMemberVar, foo()); -#define ASSIGN_OR_RETURN(lhs, stmt) ASSIGN_OR_RETURN_CONCAT(__LINE__, lhs, stmt) - -} // namespace netdutils -} // namespace android - -#endif /* NETUTILS_STATUSOR_H */ diff --git a/libnetdutils/include/netdutils/Stopwatch.h b/libnetdutils/include/netdutils/Stopwatch.h deleted file mode 100644 index e7b43264..00000000 --- a/libnetdutils/include/netdutils/Stopwatch.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NETDUTILS_STOPWATCH_H -#define NETDUTILS_STOPWATCH_H - -#include <chrono> - -namespace android { -namespace netdutils { - -class Stopwatch { - private: - using clock = std::chrono::steady_clock; - using time_point = std::chrono::time_point<clock>; - - public: - Stopwatch() : mStart(clock::now()) {} - virtual ~Stopwatch() = default; - - int64_t timeTakenUs() const { return getElapsedUs(clock::now()); } - int64_t getTimeAndResetUs() { - const auto& now = clock::now(); - int64_t elapsed = getElapsedUs(now); - mStart = now; - return elapsed; - } - - private: - time_point mStart; - - int64_t getElapsedUs(const time_point& now) const { - return (std::chrono::duration_cast<std::chrono::microseconds>(now - mStart)).count(); - } -}; - -} // namespace netdutils -} // namespace android - -#endif // NETDUTILS_STOPWATCH_H diff --git a/libnetdutils/include/netdutils/Syscalls.h b/libnetdutils/include/netdutils/Syscalls.h deleted file mode 100644 index 36fcd853..00000000 --- a/libnetdutils/include/netdutils/Syscalls.h +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NETDUTILS_SYSCALLS_H -#define NETDUTILS_SYSCALLS_H - -#include <memory> - -#include <net/if.h> -#include <poll.h> -#include <sys/eventfd.h> -#include <sys/socket.h> -#include <sys/types.h> -#include <sys/uio.h> -#include <unistd.h> - -#include "netdutils/Fd.h" -#include "netdutils/Slice.h" -#include "netdutils/Socket.h" -#include "netdutils/Status.h" -#include "netdutils/StatusOr.h" -#include "netdutils/UniqueFd.h" -#include "netdutils/UniqueFile.h" - -namespace android { -namespace netdutils { - -class Syscalls { - public: - virtual ~Syscalls() = default; - - virtual StatusOr<UniqueFd> open(const std::string& pathname, int flags, - mode_t mode = 0) const = 0; - - virtual StatusOr<UniqueFd> socket(int domain, int type, int protocol) const = 0; - - virtual Status getsockname(Fd sock, sockaddr* addr, socklen_t* addrlen) const = 0; - - virtual Status getsockopt(Fd sock, int level, int optname, void *optval, - socklen_t *optlen) const = 0; - - virtual Status setsockopt(Fd sock, int level, int optname, const void* optval, - socklen_t optlen) const = 0; - - virtual Status bind(Fd sock, const sockaddr* addr, socklen_t addrlen) const = 0; - - virtual Status connect(Fd sock, const sockaddr* addr, socklen_t addrlen) const = 0; - - virtual StatusOr<ifreq> ioctl(Fd sock, unsigned long request, ifreq* ifr) const = 0; - - virtual StatusOr<UniqueFd> eventfd(unsigned int initval, int flags) const = 0; - - virtual StatusOr<int> ppoll(pollfd* fds, nfds_t nfds, double timeout) const = 0; - - virtual StatusOr<size_t> writev(Fd fd, const std::vector<iovec>& iov) const = 0; - - virtual StatusOr<size_t> write(Fd fd, const Slice buf) const = 0; - - virtual StatusOr<Slice> read(Fd fd, const Slice buf) const = 0; - - virtual StatusOr<size_t> sendto(Fd sock, const Slice buf, int flags, const sockaddr* dst, - socklen_t dstlen) const = 0; - - virtual StatusOr<Slice> recvfrom(Fd sock, const Slice dst, int flags, sockaddr* src, - socklen_t* srclen) const = 0; - - virtual Status shutdown(Fd fd, int how) const = 0; - - virtual Status close(Fd fd) const = 0; - - virtual StatusOr<UniqueFile> fopen(const std::string& path, const std::string& mode) const = 0; - - virtual StatusOr<int> vfprintf(FILE* file, const char* format, va_list ap) const = 0; - - virtual StatusOr<int> vfscanf(FILE* file, const char* format, va_list ap) const = 0; - - virtual Status fclose(FILE* file) const = 0; - - virtual StatusOr<pid_t> fork() const = 0; - - // va_args helpers - // va_start doesn't work when the preceding argument is a reference - // type so we're forced to use const char*. - StatusOr<int> fprintf(FILE* file, const char* format, ...) const { - va_list ap; - va_start(ap, format); - auto result = vfprintf(file, format, ap); - va_end(ap); - return result; - } - - // va_start doesn't work when the preceding argument is a reference - // type so we're forced to use const char*. - StatusOr<int> fscanf(FILE* file, const char* format, ...) const { - va_list ap; - va_start(ap, format); - auto result = vfscanf(file, format, ap); - va_end(ap); - return result; - } - - // Templated helpers that forward directly to methods declared above - template <typename SockaddrT> - StatusOr<SockaddrT> getsockname(Fd sock) const { - SockaddrT addr = {}; - socklen_t addrlen = sizeof(addr); - RETURN_IF_NOT_OK(getsockname(sock, asSockaddrPtr(&addr), &addrlen)); - return addr; - } - - template <typename SockoptT> - Status getsockopt(Fd sock, int level, int optname, void* optval, socklen_t* optlen) const { - return getsockopt(sock, level, optname, optval, optlen); - } - - template <typename SockoptT> - Status setsockopt(Fd sock, int level, int optname, const SockoptT& opt) const { - return setsockopt(sock, level, optname, &opt, sizeof(opt)); - } - - template <typename SockaddrT> - Status bind(Fd sock, const SockaddrT& addr) const { - return bind(sock, asSockaddrPtr(&addr), sizeof(addr)); - } - - template <typename SockaddrT> - Status connect(Fd sock, const SockaddrT& addr) const { - return connect(sock, asSockaddrPtr(&addr), sizeof(addr)); - } - - template <size_t size> - StatusOr<std::array<uint16_t, size>> ppoll(const std::array<Fd, size>& fds, uint16_t events, - double timeout) const { - std::array<pollfd, size> tmp; - for (size_t i = 0; i < size; ++i) { - tmp[i].fd = fds[i].get(); - tmp[i].events = events; - tmp[i].revents = 0; - } - RETURN_IF_NOT_OK(ppoll(tmp.data(), tmp.size(), timeout).status()); - std::array<uint16_t, size> out; - for (size_t i = 0; i < size; ++i) { - out[i] = tmp[i].revents; - } - return out; - } - - template <typename SockaddrT> - StatusOr<size_t> sendto(Fd sock, const Slice buf, int flags, const SockaddrT& dst) const { - return sendto(sock, buf, flags, asSockaddrPtr(&dst), sizeof(dst)); - } - - // Ignore src sockaddr - StatusOr<Slice> recvfrom(Fd sock, const Slice dst, int flags) const { - return recvfrom(sock, dst, flags, nullptr, nullptr); - } - - template <typename SockaddrT> - StatusOr<std::pair<Slice, SockaddrT>> recvfrom(Fd sock, const Slice dst, int flags) const { - SockaddrT addr = {}; - socklen_t addrlen = sizeof(addr); - ASSIGN_OR_RETURN(auto used, recvfrom(sock, dst, flags, asSockaddrPtr(&addr), &addrlen)); - return std::make_pair(used, addr); - } -}; - -// Specialized singleton that supports zero initialization and runtime -// override of contained pointer. -class SyscallsHolder { - public: - ~SyscallsHolder(); - - // Return a pointer to an unowned instance of Syscalls. - Syscalls& get(); - - // Testing only: set the value returned by getSyscalls. Return the old value. - // Callers are responsible for restoring the previous value returned - // by getSyscalls to avoid leaks. - Syscalls& swap(Syscalls& syscalls); - - private: - std::atomic<Syscalls*> mSyscalls{nullptr}; -}; - -// Syscalls instance used throughout netdutils -extern SyscallsHolder sSyscalls; - -} // namespace netdutils -} // namespace android - -#endif /* NETDUTILS_SYSCALLS_H */ diff --git a/libnetdutils/include/netdutils/ThreadUtil.h b/libnetdutils/include/netdutils/ThreadUtil.h deleted file mode 100644 index 62e6f70c..00000000 --- a/libnetdutils/include/netdutils/ThreadUtil.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NETDUTILS_THREADUTIL_H -#define NETDUTILS_THREADUTIL_H - -#include <pthread.h> -#include <memory> - -#include <android-base/logging.h> - -namespace android { -namespace netdutils { - -struct scoped_pthread_attr { - scoped_pthread_attr() { pthread_attr_init(&attr); } - ~scoped_pthread_attr() { pthread_attr_destroy(&attr); } - - int detach() { return -pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); } - - pthread_attr_t attr; -}; - -inline void setThreadName(std::string name) { - // MAX_TASK_COMM_LEN=16 is not exported by bionic. - const size_t MAX_TASK_COMM_LEN = 16; - - // Crop name to 16 bytes including the NUL byte, as required by pthread_setname_np() - if (name.size() >= MAX_TASK_COMM_LEN) name.resize(MAX_TASK_COMM_LEN - 1); - - if (int ret = pthread_setname_np(pthread_self(), name.c_str()); ret != 0) { - LOG(WARNING) << "Unable to set thread name to " << name << ": " << strerror(ret); - } -} - -template <typename T> -inline void* runAndDelete(void* obj) { - std::unique_ptr<T> handler(reinterpret_cast<T*>(obj)); - setThreadName(handler->threadName().c_str()); - handler->run(); - return nullptr; -} - -template <typename T> -inline int threadLaunch(T* obj) { - if (obj == nullptr) { - return -EINVAL; - } - - scoped_pthread_attr scoped_attr; - - int rval = scoped_attr.detach(); - if (rval != 0) { - return rval; - } - - pthread_t thread; - rval = pthread_create(&thread, &scoped_attr.attr, &runAndDelete<T>, obj); - if (rval != 0) { - LOG(WARNING) << __func__ << ": pthread_create failed: " << rval; - return -rval; - } - - return rval; -} - -} // namespace netdutils -} // namespace android - -#endif // NETDUTILS_THREADUTIL_H diff --git a/libnetdutils/include/netdutils/UidConstants.h b/libnetdutils/include/netdutils/UidConstants.h deleted file mode 100644 index 42c10908..00000000 --- a/libnetdutils/include/netdutils/UidConstants.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NETDUTILS_UID_CONSTANTS_H -#define NETDUTILS_UID_CONSTANTS_H - -// These are used by both eBPF kernel programs and netd, we cannot put them in NetdConstant.h since -// we have to minimize the number of headers included by the BPF kernel program. -#define MIN_SYSTEM_UID 0 -#define MAX_SYSTEM_UID 9999 - -#define PER_USER_RANGE 100000 - -#endif // NETDUTILS_UID_CONSTANTS_H diff --git a/libnetdutils/include/netdutils/UniqueFd.h b/libnetdutils/include/netdutils/UniqueFd.h deleted file mode 100644 index 61101f95..00000000 --- a/libnetdutils/include/netdutils/UniqueFd.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NETUTILS_UNIQUEFD_H -#define NETUTILS_UNIQUEFD_H - -#include <unistd.h> -#include <ostream> - -#include "netdutils/Fd.h" - -namespace android { -namespace netdutils { - -// Stricter unique_fd implementation that: -// *) Does not implement release() -// *) Does not implicitly cast to int -// *) Uses a strongly typed wrapper (Fd) for the underlying file descriptor -// -// Users of UniqueFd should endeavor to treat this as a completely -// opaque object. The only code that should interpret the wrapped -// value is in Syscalls.h -class UniqueFd { - public: - UniqueFd() = default; - - UniqueFd(Fd fd) : mFd(fd) {} - - ~UniqueFd() { reset(); } - - // Disallow copy - UniqueFd(const UniqueFd&) = delete; - UniqueFd& operator=(const UniqueFd&) = delete; - - // Allow move - UniqueFd(UniqueFd&& other) { std::swap(mFd, other.mFd); } - UniqueFd& operator=(UniqueFd&& other) { - std::swap(mFd, other.mFd); - return *this; - } - - // Cleanup any currently owned Fd, replacing it with the optional - // parameter fd - void reset(Fd fd = Fd()); - - // Implict cast to Fd - operator const Fd &() const { return mFd; } - - private: - Fd mFd; -}; - -std::ostream& operator<<(std::ostream& os, const UniqueFd& fd); - -} // namespace netdutils -} // namespace android - -#endif /* NETUTILS_UNIQUEFD_H */ diff --git a/libnetdutils/include/netdutils/UniqueFile.h b/libnetdutils/include/netdutils/UniqueFile.h deleted file mode 100644 index 6dd6d672..00000000 --- a/libnetdutils/include/netdutils/UniqueFile.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NETDUTILS_UNIQUEFILE_H -#define NETDUTILS_UNIQUEFILE_H - -#include <stdio.h> -#include <memory> - -namespace android { -namespace netdutils { - -struct UniqueFileDtor { - void operator()(FILE* file) const; -}; - -using UniqueFile = std::unique_ptr<FILE, UniqueFileDtor>; - -} // namespace netdutils -} // namespace android - -#endif /* NETDUTILS_UNIQUEFILE_H */ |