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

Commit a3ee7802 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 6108108 from d9920242 to rvc-release

Change-Id: I0d2a0c22a04e798d678f8dd1c7ea63b130be9675
parents 1ec4e512 d9920242
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -146,7 +146,7 @@ DnsTlsTransport::Response DnsTlsDispatcher::query(const std::list<DnsTlsServer>&
DnsTlsTransport::Response DnsTlsDispatcher::query(const DnsTlsServer& server, unsigned mark,
                                                  const Slice query, const Slice ans, int* resplen,
                                                  bool* connectTriggered) {
    uint32_t connectCounter;
    int connectCounter;
    const Key key = std::make_pair(mark, server);
    Transport* xport;
    {
+1 −1
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@ std::future<DnsTlsTransport::Result> DnsTlsTransport::query(const netdutils::Sli
    return std::move(record->result);
}

uint32_t DnsTlsTransport::getConnectCounter() const {
int DnsTlsTransport::getConnectCounter() const {
    std::lock_guard guard(mLock);
    return mConnectCounter;
}
+2 −2
Original line number Diff line number Diff line
@@ -57,7 +57,7 @@ class DnsTlsTransport : public IDnsTlsSocketObserver {
    // on networks where it doesn't actually work.
    static bool validate(const DnsTlsServer& server, unsigned netid, uint32_t mark);

    uint32_t getConnectCounter() const EXCLUDES(mLock);
    int getConnectCounter() const EXCLUDES(mLock);

    // Implement IDnsTlsSocketObserver
    void onResponse(std::vector<uint8_t> response) override;
@@ -89,7 +89,7 @@ class DnsTlsTransport : public IDnsTlsSocketObserver {
    bool sendQuery(const DnsTlsQueryMap::Query q) REQUIRES(mLock);

    // The number of times an attempt to connect the nameserver.
    uint32_t mConnectCounter GUARDED_BY(mLock) = 0;
    int mConnectCounter GUARDED_BY(mLock) = 0;
};

}  // end of namespace net
+16 −17
Original line number Diff line number Diff line
@@ -148,7 +148,7 @@ TEST_F(TransportTest, Query) {

    EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
    EXPECT_EQ(QUERY, r.response);
    EXPECT_EQ(transport.getConnectCounter(), 1U);
    EXPECT_EQ(transport.getConnectCounter(), 1);
}

// Fake Socket that echoes the observed query ID as the response body.
@@ -189,7 +189,7 @@ TEST_F(TransportTest, IdReuse) {
        // after each use.
        EXPECT_EQ(0, (r.response[2] << 8) | r.response[3]);
    }
    EXPECT_EQ(transport.getConnectCounter(), 1U);
    EXPECT_EQ(transport.getConnectCounter(), 1);
}

// These queries might be handled in serial or parallel as they race the
@@ -209,7 +209,7 @@ TEST_F(TransportTest, RacingQueries_10000) {
        EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
        EXPECT_EQ(QUERY, r.response);
    }
    EXPECT_EQ(transport.getConnectCounter(), 1U);
    EXPECT_EQ(transport.getConnectCounter(), 1);
}

// A server that waits until sDelay queries are queued before responding.
@@ -275,7 +275,7 @@ TEST_F(TransportTest, ParallelColliding) {
        EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
        EXPECT_EQ(QUERY, r.response);
    }
    EXPECT_EQ(transport.getConnectCounter(), 1U);
    EXPECT_EQ(transport.getConnectCounter(), 1);
}

TEST_F(TransportTest, ParallelColliding_Max) {
@@ -295,7 +295,7 @@ TEST_F(TransportTest, ParallelColliding_Max) {
        EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
        EXPECT_EQ(QUERY, r.response);
    }
    EXPECT_EQ(transport.getConnectCounter(), 1U);
    EXPECT_EQ(transport.getConnectCounter(), 1);
}

TEST_F(TransportTest, ParallelUnique) {
@@ -315,7 +315,7 @@ TEST_F(TransportTest, ParallelUnique) {
        EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
        EXPECT_EQ(queries[i], r.response);
    }
    EXPECT_EQ(transport.getConnectCounter(), 1U);
    EXPECT_EQ(transport.getConnectCounter(), 1);
}

TEST_F(TransportTest, ParallelUnique_Max) {
@@ -337,7 +337,7 @@ TEST_F(TransportTest, ParallelUnique_Max) {
        EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
        EXPECT_EQ(queries[i], r.response);
    }
    EXPECT_EQ(transport.getConnectCounter(), 1U);
    EXPECT_EQ(transport.getConnectCounter(), 1);
}

TEST_F(TransportTest, IdExhaustion) {
@@ -365,7 +365,7 @@ TEST_F(TransportTest, IdExhaustion) {
        EXPECT_EQ(std::future_status::timeout,
                result.wait_for(std::chrono::duration<int>::zero()));
    }
    EXPECT_EQ(transport.getConnectCounter(), 1U);
    EXPECT_EQ(transport.getConnectCounter(), 1);
}

// Responses can come back from the server in any order.  This should have no
@@ -387,7 +387,7 @@ TEST_F(TransportTest, ReverseOrder) {
        EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
        EXPECT_EQ(queries[i], r.response);
    }
    EXPECT_EQ(transport.getConnectCounter(), 1U);
    EXPECT_EQ(transport.getConnectCounter(), 1);
}

TEST_F(TransportTest, ReverseOrder_Max) {
@@ -407,7 +407,7 @@ TEST_F(TransportTest, ReverseOrder_Max) {
        EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
        EXPECT_EQ(queries[i], r.response);
    }
    EXPECT_EQ(transport.getConnectCounter(), 1U);
    EXPECT_EQ(transport.getConnectCounter(), 1);
}

// Returning null from the factory indicates a connection failure.
@@ -430,7 +430,7 @@ TEST_F(TransportTest, ConnectFail) {

    EXPECT_EQ(DnsTlsTransport::Response::network_error, r.code);
    EXPECT_TRUE(r.response.empty());
    EXPECT_EQ(transport.getConnectCounter(), 1U);
    EXPECT_EQ(transport.getConnectCounter(), 1);
}

// Simulate a socket that connects but then immediately receives a server
@@ -458,7 +458,7 @@ TEST_F(TransportTest, CloseRetryFail) {
    EXPECT_TRUE(r.response.empty());

    // Reconnections are triggered since DnsTlsQueryMap is not empty.
    EXPECT_EQ(transport.getConnectCounter(), static_cast<uint32_t>(DnsTlsQueryMap::kMaxTries));
    EXPECT_EQ(transport.getConnectCounter(), DnsTlsQueryMap::kMaxTries);
}

// Simulate a server that occasionally closes the connection and silently
@@ -553,7 +553,7 @@ TEST_F(TransportTest, SilentDrop) {
    }

    // Reconnections are triggered since DnsTlsQueryMap is not empty.
    EXPECT_EQ(transport.getConnectCounter(), static_cast<uint32_t>(DnsTlsQueryMap::kMaxTries));
    EXPECT_EQ(transport.getConnectCounter(), DnsTlsQueryMap::kMaxTries);
}

TEST_F(TransportTest, PartialDrop) {
@@ -590,7 +590,7 @@ TEST_F(TransportTest, ConnectCounter) {
    DnsTlsTransport transport(SERVER1, MARK, &factory);

    // Connecting on demand.
    EXPECT_EQ(transport.getConnectCounter(), 0U);
    EXPECT_EQ(transport.getConnectCounter(), 0);

    const int num_queries = 10;
    std::vector<std::future<DnsTlsTransport::Result>> results;
@@ -604,8 +604,7 @@ TEST_F(TransportTest, ConnectCounter) {
        EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
    }

    EXPECT_EQ(transport.getConnectCounter(),
              static_cast<uint32_t>(num_queries / FakeSocketLimited::sLimit));
    EXPECT_EQ(transport.getConnectCounter(), num_queries / FakeSocketLimited::sLimit);
}

// Simulate a malfunctioning server that injects extra miscellaneous
@@ -649,7 +648,7 @@ TEST_F(TransportTest, IgnoringGarbage) {
        EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
        // Don't check the response because this server is malfunctioning.
    }
    EXPECT_EQ(transport.getConnectCounter(), 1U);
    EXPECT_EQ(transport.getConnectCounter(), 1);
}

// Dispatcher tests
+79 −18
Original line number Diff line number Diff line
@@ -623,6 +623,15 @@ void DNSResponder::clearQueries() {
    queries_.clear();
}

bool DNSResponder::hasOptPseudoRR(DNSHeader* header) const {
    if (header->additionals.empty()) return false;

    // OPT RR may be placed anywhere within the additional section. See RFC 6891 section 6.1.1.
    auto found = std::find_if(header->additionals.begin(), header->additionals.end(),
                              [](const auto& a) { return a.rtype == ns_type::ns_t_opt; });
    return found != header->additionals.end();
}

void DNSResponder::requestHandler() {
    epoll_event evs[EPOLL_MAX_EVENTS];
    while (true) {
@@ -713,15 +722,7 @@ bool DNSResponder::handleDNSRequest(const char* buffer, ssize_t len, int protoco

    // Make the response. The query has been read into |header| which is used to build and return
    // the response as well.
    switch (mapping_type_) {
        case MappingType::DNS_HEADER:
            return makeResponseFromDnsHeader(&header, response, response_len);
        case MappingType::BINARY_PACKET:
            return makeResponseFromBinaryPacket(&header, response, response_len);
        case MappingType::ADDRESS_OR_HOSTNAME:
        default:
            return makeResponse(&header, response, response_len);
    }
    return makeResponse(&header, protocol, response, response_len);
}

bool DNSResponder::addAnswerRecords(const DNSQuestion& question,
@@ -841,7 +842,66 @@ bool DNSResponder::makeErrorResponse(DNSHeader* header, ns_rcode rcode, char* re
    return writePacket(header, response, response_len);
}

bool DNSResponder::makeResponse(DNSHeader* header, char* response, size_t* response_len) const {
bool DNSResponder::makeTruncatedResponse(DNSHeader* header, char* response,
                                         size_t* response_len) const {
    // Build a minimal response for non-EDNS response over UDP. Truncate all stub RRs in answer,
    // authority and additional section. EDNS response truncation has not supported here yet
    // because the EDNS response must have an OPT record. See RFC 6891 section 7.
    header->answers.clear();
    header->authorities.clear();
    header->additionals.clear();
    header->qr = true;
    header->tr = true;
    return writePacket(header, response, response_len);
}

bool DNSResponder::makeResponse(DNSHeader* header, int protocol, char* response,
                                size_t* response_len) const {
    char buffer[4096];
    size_t buffer_len = sizeof(buffer);
    bool ret;

    switch (mapping_type_) {
        case MappingType::DNS_HEADER:
            ret = makeResponseFromDnsHeader(header, buffer, &buffer_len);
            break;
        case MappingType::BINARY_PACKET:
            ret = makeResponseFromBinaryPacket(header, buffer, &buffer_len);
            break;
        case MappingType::ADDRESS_OR_HOSTNAME:
        default:
            ret = makeResponseFromAddressOrHostname(header, buffer, &buffer_len);
    }

    if (!ret) return false;

    // Return truncated response if the built non-EDNS response size which is larger than 512 bytes
    // will be responded over UDP. The truncated response implementation here just simply set up
    // the TC bit and truncate all stub RRs in answer, authority and additional section. It is
    // because the resolver will retry DNS query over TCP and use the full TCP response. See also
    // RFC 1035 section 4.2.1 for UDP response truncation and RFC 6891 section 4.3 for EDNS larger
    // response size capability.
    // TODO: Perhaps keep the stub RRs as possible.
    // TODO: Perhaps truncate the EDNS based response over UDP. See also RFC 6891 section 4.3,
    // section 6.2.5 and section 7.
    if (protocol == IPPROTO_UDP && buffer_len > kMaximumUdpSize &&
        !hasOptPseudoRR(header) /* non-EDNS */) {
        LOG(INFO) << "Return truncated response because original response length " << buffer_len
                  << " is larger than " << kMaximumUdpSize << " bytes.";
        return makeTruncatedResponse(header, response, response_len);
    }

    if (buffer_len > *response_len) {
        LOG(ERROR) << "buffer overflow on line " << __LINE__;
        return false;
    }
    memcpy(response, buffer, buffer_len);
    *response_len = buffer_len;
    return true;
}

bool DNSResponder::makeResponseFromAddressOrHostname(DNSHeader* header, char* response,
                                                     size_t* response_len) const {
    for (const DNSQuestion& question : header->questions) {
        if (question.qclass != ns_class::ns_c_in && question.qclass != ns_class::ns_c_any) {
            LOG(INFO) << "unsupported question class " << question.qclass;
@@ -894,9 +954,9 @@ bool DNSResponder::makeResponseFromDnsHeader(DNSHeader* header, char* response,
        LOG(INFO) << "no mapping found for " << name << " " << dnstype2str(qtype)
                  << ", couldn't build a response from DNSHeader mapping";

        // Note that do nothing as makeResponse() if no mapping is found. It just changes the QR
        // flag from query (0) to response (1) in the query. Then, send the modified query back as
        // a response.
        // Note that do nothing as makeResponseFromAddressOrHostname() if no mapping is found. It
        // just changes the QR flag from query (0) to response (1) in the query. Then, send the
        // modified query back as a response.
        header->qr = true;
    }
    return writePacket(header, response, response_len);
@@ -932,9 +992,9 @@ bool DNSResponder::makeResponseFromBinaryPacket(DNSHeader* header, char* respons
        // TODO: handle correctly. See also TODO in addAnswerRecords().
        // TODO: Perhaps dump packet content to indicate which query failed.
        LOG(INFO) << "no mapping found, couldn't build a response from BinaryPacket mapping";
        // Note that do nothing as makeResponse() if no mapping is found. It just changes the QR
        // flag from query (0) to response (1) in the query. Then, send the modified query back as
        // a response.
        // Note that do nothing as makeResponseFromAddressOrHostname() if no mapping is found. It
        // just changes the QR flag from query (0) to response (1) in the query. Then, send the
        // modified query back as a response.
        header->qr = true;
        return writePacket(header, response, response_len);
    }
@@ -1049,8 +1109,9 @@ void DNSResponder::handleQuery(int protocol) {
            LOG(ERROR) << method_str << " failed for " << host_str;
        }
        // Test that the response is actually a correct DNS message.
        // TODO: Make DNS message test to support name compression. Or it throws a warning for
        // a valid DNS message with name compression while the raw packet mapping is used.
        // TODO: Perhaps make DNS message validation to support name compression. Or it throws
        // a warning for a valid DNS message with name compression while the binary packet mapping
        // is used.
        const char* response_end = response + len;
        DNSHeader header;
        const char* cur = header.read(response, response_end);
Loading