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

Commit 14e0a78a authored by Ken Chen's avatar Ken Chen
Browse files

Support setting response probability by protocol

The response probability can be set per protocol. It can be utilized in
test case to control whether DNSResponder supports TCP or UDP
connection.

Change-Id: I61a0629c2b4eaf583c836875bca44cd7cf3971e0
parent c90b4a07
Loading
Loading
Loading
Loading
+32 −2
Original line number Diff line number Diff line
@@ -509,8 +509,38 @@ void DNSResponder::removeMappingBinaryPacket(const std::vector<uint8_t>& query)
    }
}

// Set response probability on all supported protocols.
void DNSResponder::setResponseProbability(double response_probability) {
    response_probability_ = response_probability;
    setResponseProbability(response_probability, IPPROTO_TCP);
    setResponseProbability(response_probability, IPPROTO_UDP);
}

// Set response probability on specific protocol. It's caller's duty to ensure that the |protocol|
// can be supported by DNSResponder.
void DNSResponder::setResponseProbability(double response_probability, int protocol) {
    switch (protocol) {
        case IPPROTO_TCP:
            response_probability_tcp_ = response_probability;
            break;
        case IPPROTO_UDP:
            response_probability_udp_ = response_probability;
            break;
        default:
            LOG(FATAL) << "Unsupported protocol " << protocol;  // abort() by log level FATAL
    }
}

double DNSResponder::getResponseProbability(int protocol) const {
    switch (protocol) {
        case IPPROTO_TCP:
            return response_probability_tcp_;
        case IPPROTO_UDP:
            return response_probability_udp_;
        default:
            LOG(FATAL) << "Unsupported protocol " << protocol;  // abort() by log level FATAL
            // unreachable
            return -1;
    }
}

void DNSResponder::setEdns(Edns edns) {
@@ -709,7 +739,7 @@ bool DNSResponder::handleDNSRequest(const char* buffer, ssize_t len, int protoco
    }
    // Ignore requests with the preset probability.
    auto constexpr bound = std::numeric_limits<unsigned>::max();
    if (arc4random_uniform(bound) > bound * response_probability_) {
    if (arc4random_uniform(bound) > bound * getResponseProbability(protocol)) {
        if (error_rcode_ < 0) {
            LOG(ERROR) << "Returning no response";
            return false;
+10 −3
Original line number Diff line number Diff line
@@ -173,6 +173,7 @@ class DNSResponder {
    void removeMappingBinaryPacket(const std::vector<uint8_t>& query);

    void setResponseProbability(double response_probability);
    void setResponseProbability(double response_probability, int protocol);
    void setEdns(Edns edns);
    bool running() const;
    bool startServer();
@@ -276,6 +277,8 @@ class DNSResponder {
    // TODO: Move createListeningSocket to resolv_test_utils.h
    android::base::unique_fd createListeningSocket(int socket_type);

    double getResponseProbability(int protocol) const;

    // Address and service to listen on TCP and UDP.
    const std::string listen_address_;
    const std::string listen_service_;
@@ -283,9 +286,13 @@ class DNSResponder {
    const ns_rcode error_rcode_;
    // Mapping type the DNS server used to build the response.
    const MappingType mapping_type_;
    // Probability that a valid response is being sent instead of being sent
    // instead of returning error_rcode_.
    std::atomic<double> response_probability_ = 1.0;
    // Probability that a valid response on TCP is being sent instead of
    // returning error_rcode_ or no response.
    std::atomic<double> response_probability_tcp_ = 1.0;
    // Probability that a valid response on UDP is being sent instead of
    // returning error_rcode_ or no response.
    std::atomic<double> response_probability_udp_ = 1.0;

    // Maximum number of fds for epoll.
    const int EPOLL_MAX_EVENTS = 2;