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

Commit 358d8ca9 authored by Mike Yu's avatar Mike Yu Committed by Automerger Merge Worker
Browse files

Retry binding sockets in DNSResponder if errno is EADDRNOTAVAIL am: db04a2bd...

Retry binding sockets in DNSResponder if errno is EADDRNOTAVAIL am: db04a2bd am: 909f4433 am: 07be7930

Original change: https://android-review.googlesource.com/c/platform/packages/modules/DnsResolver/+/1688185

Change-Id: I05a795e7c19b58023c04142d31450e1fffd38577
parents 154d1dbd 07be7930
Loading
Loading
Loading
Loading
+31 −1
Original line number Diff line number Diff line
@@ -36,13 +36,16 @@
#define LOG_TAG "DNSResponder"
#include <android-base/logging.h>
#include <android-base/strings.h>
#include <netdutils/BackoffSequence.h>
#include <netdutils/InternetAddresses.h>
#include <netdutils/Slice.h>
#include <netdutils/SocketOption.h>

using android::netdutils::BackoffSequence;
using android::netdutils::enableSockopt;
using android::netdutils::ScopedAddrinfo;
using android::netdutils::Slice;
using std::chrono::milliseconds;

namespace test {

@@ -71,6 +74,33 @@ std::string addr2str(const sockaddr* sa, socklen_t sa_len) {
    return std::string();
}

// Because The address might still being set up (b/186181084), This is a wrapper function
// that retries bind() if errno is EADDRNOTAVAIL
int bindSocket(int socket, const sockaddr* address, socklen_t address_len) {
    // Set the wrapper to try bind() at most 6 times with backoff time
    // (100 ms, 200 ms, ..., 1600 ms).
    auto backoff = BackoffSequence<milliseconds>::Builder()
                           .withInitialRetransmissionTime(milliseconds(100))
                           .withMaximumRetransmissionCount(5)
                           .build();

    while (true) {
        int ret = bind(socket, address, address_len);
        if (ret == 0 || errno != EADDRNOTAVAIL) {
            return ret;
        }

        if (!backoff.hasNextTimeout()) break;

        LOG(WARNING) << "Retry to bind " << addr2str(address, address_len);
        std::this_thread::sleep_for(backoff.getNextTimeout());
    }

    // Set errno before return since it might have been changed somewhere.
    errno = EADDRNOTAVAIL;
    return -1;
}

/* DNS struct helpers */

const char* dnstype2str(unsigned dnstype) {
@@ -1206,7 +1236,7 @@ android::base::unique_fd DNSResponder::createListeningSocket(int socket_type) {
        const std::string host_str = addr2str(ai->ai_addr, ai->ai_addrlen);
        const char* socket_str = (socket_type == SOCK_STREAM) ? "TCP" : "UDP";

        if (bind(fd.get(), ai->ai_addr, ai->ai_addrlen)) {
        if (bindSocket(fd.get(), ai->ai_addr, ai->ai_addrlen)) {
            PLOG(ERROR) << "failed to bind " << socket_str << " " << host_str << ":"
                        << listen_service_;
            continue;