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

Commit c4154b2d 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 am: 358d8ca9

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

Change-Id: Ia8bac1390d6898e7b5857a4fdb44a478bea069e2
parents 2c31c62f 358d8ca9
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;