Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 55525d1c authored by Ken Chen's avatar Ken Chen
Browse files

Replace hardcoded metered info by the real setting

Pass the actual metered information into
ADnsHelper_isUidNetworkingBlocked().

Extend an existing test so that it can verify the data saver feature on
a metered network.

Bug: 288340533
Test: atest resolv_integration_test
Change-Id: I5e9ac44d0ab78f4ec48f320fbf23393e63e3898b
parent 69390aa5
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -706,8 +706,7 @@ bool isUidNetworkingBlocked(uid_t uid, unsigned netId) {
    // application's UID. Its DNS packets are not subject to certain network restriction features.
    if (resolv_is_enforceDnsUid_enabled_network(netId)) return false;

    // TODO: Pass metered information from CS to DNS resolver and replace the hardcode value.
    return (*ADnsHelper_isUidNetworkingBlocked)(uid, /*metered=*/false) == 1;
    return (*ADnsHelper_isUidNetworkingBlocked)(uid, resolv_is_metered_network(netId)) == 1;
}

}  // namespace
+42 −26
Original line number Diff line number Diff line
@@ -345,6 +345,28 @@ class BasePrivateDnsTest : public BaseTest {
        EXPECT_EQ(mDnsClient.resolvService()->dump(fd, querylogCmd, std::size(querylogCmd)), 0);
    }

    void expectQueriesAreBlocked() {
        // getaddrinfo should fail
        const addrinfo hints = {.ai_socktype = SOCK_DGRAM};
        EXPECT_FALSE(safe_getaddrinfo(kQueryHostname, nullptr, &hints));

        // gethostbyname should fail
        EXPECT_FALSE(gethostbyname(kQueryHostname));

        // gethostbyaddr should fail
        in6_addr v6addr;
        inet_pton(AF_INET6, "2001:db8::102:304", &v6addr);
        EXPECT_FALSE(gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6));

        // resNetworkQuery should fail
        int fd = resNetworkQuery(TEST_NETID, kQueryHostname, ns_c_in, ns_t_aaaa, 0);
        EXPECT_TRUE(fd != -1);

        uint8_t buf[MAXPACKET] = {};
        int rcode;
        EXPECT_EQ(-ECONNREFUSED, getAsyncResponse(fd, &rcode, buf, MAXPACKET));
    }

    static constexpr milliseconds kExpectedDohValidationTimeWhenTimeout{1000};
    static constexpr milliseconds kExpectedDohValidationTimeWhenServerUnreachable{1000};
    static constexpr char kQueryHostname[] = "TransportParameterizedTest.example.com.";
@@ -528,7 +550,7 @@ TEST_P(TransportParameterizedTest, MdnsGetAddrInfo_fallback) {
    }
}

TEST_P(TransportParameterizedTest, BlockDnsQueryWithUidRule) {
TEST_P(TransportParameterizedTest, BlockDnsQuery) {
    SKIP_IF_BEFORE_T;
    constexpr char ptr_name[] = "v4v6.example.com.";
    // PTR record for IPv6 address 2001:db8::102:304
@@ -539,7 +561,7 @@ TEST_P(TransportParameterizedTest, BlockDnsQueryWithUidRule) {
    dot_backend.addMapping(r.host_name, r.type, r.addr);
    doh_backend.addMapping(r.host_name, r.type, r.addr);

    const auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
    auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
    ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));

    if (testParamHasDoh()) EXPECT_TRUE(WaitForDohValidationSuccess(test::kDefaultListenAddr));
@@ -559,31 +581,25 @@ TEST_P(TransportParameterizedTest, BlockDnsQueryWithUidRule) {
    }
    dns.clearQueries();

    // Block TEST_UID's network access
    ScopeBlockedUIDRule scopeBlockUidRule(mDnsClient.netdService(), TEST_UID);

    // getaddrinfo should fail
    const addrinfo hints = {.ai_socktype = SOCK_DGRAM};
    EXPECT_FALSE(safe_getaddrinfo(kQueryHostname, nullptr, &hints));

    // gethostbyname should fail
    EXPECT_FALSE(gethostbyname(kQueryHostname));

    // gethostbyaddr should fail
    in6_addr v6addr;
    inet_pton(AF_INET6, "2001:db8::102:304", &v6addr);
    EXPECT_FALSE(gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6));

    // resNetworkQuery should fail
    int fd = resNetworkQuery(TEST_NETID, kQueryHostname, ns_c_in, ns_t_aaaa, 0);
    EXPECT_TRUE(fd != -1);

    uint8_t buf[MAXPACKET] = {};
    int rcode;
    EXPECT_EQ(-ECONNREFUSED, getAsyncResponse(fd, &rcode, buf, MAXPACKET));
    for (const bool testDataSaver : {false, true}) {
        SCOPED_TRACE(fmt::format("test {}", testDataSaver ? "data saver" : "UID firewall rules"));
        if (testDataSaver) {
            // Data Saver applies on metered networks only.
            parcel.meteredNetwork = true;
            ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));

            // Block network access by enabling data saver.
            ScopedSetDataSaverByBPF scopedSetDataSaverByBPF(true);
            ScopedChangeUID scopedChangeUID(TEST_UID);
            expectQueriesAreBlocked();
        } else {
            // Block network access by setting UID firewall rules.
            ScopeBlockedUIDRule scopeBlockUidRule(mDnsClient.netdService(), TEST_UID);
            expectQueriesAreBlocked();
        }
        expectQueries(0 /* dns */, 0 /* dot */, 0 /* doh */);
    }
}

class PrivateDnsDohTest : public BasePrivateDnsTest {
  protected:
+27 −0
Original line number Diff line number Diff line
@@ -81,6 +81,33 @@ class ScopeBlockedUIDRule {
    const uid_t mSavedUid;
};

// Supported from T+ only.
class ScopedSetDataSaverByBPF {
  public:
    ScopedSetDataSaverByBPF(bool wanted) {
        if (android::modules::sdklevel::IsAtLeastT()) {
            mFw = Firewall::getInstance();
            // Backup current setting.
            const Result<bool> current = mFw->getDataSaverSetting();
            EXPECT_RESULT_OK(current);
            if (wanted != current.value()) {
                mSavedDataSaverSetting = current;
                EXPECT_RESULT_OK(mFw->setDataSaver(wanted));
            }
        }
    };
    ~ScopedSetDataSaverByBPF() {
        // Restore the setting.
        if (mSavedDataSaverSetting.has_value()) {
            EXPECT_RESULT_OK(mFw->setDataSaver(mSavedDataSaverSetting.value()));
        }
    }

  private:
    Firewall* mFw;
    Result<bool> mSavedDataSaverSetting;
};

class ScopedChangeUID {
  public:
    ScopedChangeUID(uid_t testUid) : mTestUid(testUid), mSavedUid(getuid()) {