Loading res_send.cpp +22 −7 Original line number Diff line number Diff line Loading @@ -130,6 +130,7 @@ using android::net::IpVersion; using android::net::IV_IPV4; using android::net::IV_IPV6; using android::net::IV_UNKNOWN; using android::net::LinuxErrno; using android::net::NetworkDnsEventReported; using android::net::NS_T_INVALID; using android::net::NsRcode; Loading Loading @@ -499,7 +500,8 @@ int res_nsend(res_state statp, const uint8_t* buf, int buflen, uint8_t* ans, int int retryTimes = (flags & ANDROID_RESOLV_NO_RETRY) ? 1 : params.retry_count; int useTcp = buflen > PACKETSZ; int gotsomewhere = 0; int terrno = ETIMEDOUT; // Use an impossible error code as default value int terrno = ETIME; for (int attempt = 0; attempt < retryTimes; ++attempt) { for (size_t ns = 0; ns < statp->nsaddrs.size(); ++ns) { Loading @@ -521,6 +523,8 @@ int res_nsend(res_state statp, const uint8_t* buf, int buflen, uint8_t* ans, int Stopwatch queryStopwatch; int retry_count_for_event = 0; size_t actualNs = ns; // Use an impossible error code as default value terrno = ETIME; if (useTcp) { // TCP; at most one attempt per server. attempt = retryTimes; Loading Loading @@ -558,6 +562,7 @@ int res_nsend(res_state statp, const uint8_t* buf, int buflen, uint8_t* ans, int dnsQueryEvent->set_rcode(static_cast<NsRcode>(*rcode)); dnsQueryEvent->set_protocol(query_proto); dnsQueryEvent->set_type(getQueryType(buf, buflen)); dnsQueryEvent->set_linux_errno(static_cast<LinuxErrno>(terrno)); // Only record stats the first time we try a query. This ensures that // queries that deterministically fail (e.g., a name that always returns Loading Loading @@ -643,6 +648,7 @@ static int send_vc(res_state statp, res_params* params, const uint8_t* buf, int // It should never happen, but just in case. if (ns >= statp->nsaddrs.size()) { LOG(ERROR) << __func__ << ": Out-of-bound indexing: " << ns; *terrno = EINVAL; return -1; } Loading Loading @@ -675,15 +681,14 @@ same_ns: statp->tcp_nssock.reset(socket(nsap->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)); if (statp->tcp_nssock < 0) { *terrno = errno; PLOG(DEBUG) << __func__ << ": socket(vc): "; switch (errno) { case EPROTONOSUPPORT: case EPFNOSUPPORT: case EAFNOSUPPORT: PLOG(DEBUG) << __func__ << ": socket(vc): "; return 0; default: *terrno = errno; PLOG(DEBUG) << __func__ << ": socket(vc): "; return -1; } } Loading Loading @@ -831,6 +836,7 @@ read_len: *delay = res_stats_calculate_rtt(&done, &start_time); *rcode = anhp->rcode; } *terrno = 0; return (resplen); } Loading Loading @@ -972,6 +978,7 @@ static int send_dg(res_state statp, res_params* params, const uint8_t* buf, int // It should never happen, but just in case. if (*ns >= statp->nsaddrs.size()) { LOG(ERROR) << __func__ << ": Out-of-bound indexing: " << ns; *terrno = EINVAL; return -1; } Loading @@ -984,15 +991,14 @@ static int send_dg(res_state statp, res_params* params, const uint8_t* buf, int if (statp->nssocks[*ns] == -1) { statp->nssocks[*ns].reset(socket(nsap->sa_family, SOCK_DGRAM | SOCK_CLOEXEC, 0)); if (statp->nssocks[*ns] < 0) { *terrno = errno; PLOG(DEBUG) << __func__ << ": socket(dg): "; switch (errno) { case EPROTONOSUPPORT: case EPFNOSUPPORT: case EAFNOSUPPORT: PLOG(DEBUG) << __func__ << ": socket(dg): "; return (0); default: *terrno = errno; PLOG(DEBUG) << __func__ << ": socket(dg): "; return (-1); } } Loading @@ -1001,6 +1007,7 @@ static int send_dg(res_state statp, res_params* params, const uint8_t* buf, int if (statp->_mark != MARK_UNSET) { if (setsockopt(statp->nssocks[*ns], SOL_SOCKET, SO_MARK, &(statp->_mark), sizeof(statp->_mark)) < 0) { *terrno = errno; statp->closeSockets(); return -1; } Loading @@ -1010,11 +1017,13 @@ static int send_dg(res_state statp, res_params* params, const uint8_t* buf, int // ICMP port-unreachable error. This way we can detect the absence of // a nameserver without timing out. if (random_bind(statp->nssocks[*ns], nsap->sa_family) < 0) { *terrno = errno; dump_error("bind(dg)", nsap, nsaplen); statp->closeSockets(); return (0); } if (connect(statp->nssocks[*ns], nsap, (socklen_t)nsaplen) < 0) { *terrno = errno; dump_error("connect(dg)", nsap, nsaplen); statp->closeSockets(); return (0); Loading @@ -1022,6 +1031,7 @@ static int send_dg(res_state statp, res_params* params, const uint8_t* buf, int LOG(DEBUG) << __func__ << ": new DG socket"; } if (send(statp->nssocks[*ns], (const char*)buf, (size_t)buflen, 0) != buflen) { *terrno = errno; PLOG(DEBUG) << __func__ << ": send: "; statp->closeSockets(); return 0; Loading @@ -1037,6 +1047,7 @@ static int send_dg(res_state statp, res_params* params, const uint8_t* buf, int if (!result.has_value()) { const bool isTimeout = (result.error().code() == ETIMEDOUT); *rcode = (isTimeout) ? RCODE_TIMEOUT : *rcode; *terrno = (isTimeout) ? ETIMEDOUT : errno; *gotsomewhere = (isTimeout) ? 1 : *gotsomewhere; // Leave the UDP sockets open on timeout so we can keep listening for // a late response from this server while retrying on the next server. Loading @@ -1052,6 +1063,7 @@ static int send_dg(res_state statp, res_params* params, const uint8_t* buf, int int resplen = recvfrom(fd, (char*)ans, (size_t)anssiz, 0, (sockaddr*)(void*)&from, &fromlen); if (resplen <= 0) { *terrno = errno; PLOG(DEBUG) << __func__ << ": recvfrom: "; continue; } Loading Loading @@ -1080,6 +1092,7 @@ static int send_dg(res_state statp, res_params* params, const uint8_t* buf, int res_pquery(ans, (resplen > anssiz) ? anssiz : resplen); // record the error statp->_flags |= RES_F_EDNS0ERR; *terrno = EREMOTEIO; continue; } Loading @@ -1095,6 +1108,7 @@ static int send_dg(res_state statp, res_params* params, const uint8_t* buf, int // To get the rest of answer, // use TCP with same server. LOG(DEBUG) << __func__ << ": truncated answer"; *terrno = E2BIG; *v_circuit = 1; return 1; } Loading @@ -1103,6 +1117,7 @@ static int send_dg(res_state statp, res_params* params, const uint8_t* buf, int *rcode = anhp->rcode; *ns = receivedFromNs; *terrno = 0; return resplen; } if (!needRetry) return 0; Loading resolv_unit_test.cpp +18 −18 Original line number Diff line number Diff line Loading @@ -668,7 +668,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 0, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, }, { rcode: 255, Loading @@ -679,7 +679,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 1, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, } { rcode: 255, Loading @@ -690,7 +690,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 0, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, }, { rcode: 255, Loading @@ -701,7 +701,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 1, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, }, { rcode: 255, Loading @@ -712,7 +712,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 0, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, }, { rcode: 255, Loading @@ -723,7 +723,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 1, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, } { rcode: 255, Loading @@ -734,7 +734,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 0, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, }, { rcode: 255, Loading @@ -745,7 +745,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 1, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, }, { rcode: 255, Loading @@ -756,7 +756,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 0, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, }, { rcode: 255, Loading @@ -767,7 +767,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 1, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, } { rcode: 255, Loading @@ -778,7 +778,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 0, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, }, { rcode: 255, Loading @@ -789,7 +789,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 1, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, }, { rcode: 255, Loading @@ -800,7 +800,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 0, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, }, { rcode: 255, Loading @@ -811,7 +811,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 1, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, } { rcode: 255, Loading @@ -822,7 +822,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 0, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, }, { rcode: 255, Loading @@ -833,7 +833,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 1, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, }, ] } Loading Loading @@ -1026,7 +1026,7 @@ TEST_F(ResolvGetAddrInfoTest, TruncatedResponse) { retry_times: 0, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 7, }, { rcode: 0, Loading Loading @@ -1068,7 +1068,7 @@ TEST_F(ResolvGetAddrInfoTest, TruncatedResponse) { retry_times: 0, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 7, }, { rcode: 0, Loading Loading
res_send.cpp +22 −7 Original line number Diff line number Diff line Loading @@ -130,6 +130,7 @@ using android::net::IpVersion; using android::net::IV_IPV4; using android::net::IV_IPV6; using android::net::IV_UNKNOWN; using android::net::LinuxErrno; using android::net::NetworkDnsEventReported; using android::net::NS_T_INVALID; using android::net::NsRcode; Loading Loading @@ -499,7 +500,8 @@ int res_nsend(res_state statp, const uint8_t* buf, int buflen, uint8_t* ans, int int retryTimes = (flags & ANDROID_RESOLV_NO_RETRY) ? 1 : params.retry_count; int useTcp = buflen > PACKETSZ; int gotsomewhere = 0; int terrno = ETIMEDOUT; // Use an impossible error code as default value int terrno = ETIME; for (int attempt = 0; attempt < retryTimes; ++attempt) { for (size_t ns = 0; ns < statp->nsaddrs.size(); ++ns) { Loading @@ -521,6 +523,8 @@ int res_nsend(res_state statp, const uint8_t* buf, int buflen, uint8_t* ans, int Stopwatch queryStopwatch; int retry_count_for_event = 0; size_t actualNs = ns; // Use an impossible error code as default value terrno = ETIME; if (useTcp) { // TCP; at most one attempt per server. attempt = retryTimes; Loading Loading @@ -558,6 +562,7 @@ int res_nsend(res_state statp, const uint8_t* buf, int buflen, uint8_t* ans, int dnsQueryEvent->set_rcode(static_cast<NsRcode>(*rcode)); dnsQueryEvent->set_protocol(query_proto); dnsQueryEvent->set_type(getQueryType(buf, buflen)); dnsQueryEvent->set_linux_errno(static_cast<LinuxErrno>(terrno)); // Only record stats the first time we try a query. This ensures that // queries that deterministically fail (e.g., a name that always returns Loading Loading @@ -643,6 +648,7 @@ static int send_vc(res_state statp, res_params* params, const uint8_t* buf, int // It should never happen, but just in case. if (ns >= statp->nsaddrs.size()) { LOG(ERROR) << __func__ << ": Out-of-bound indexing: " << ns; *terrno = EINVAL; return -1; } Loading Loading @@ -675,15 +681,14 @@ same_ns: statp->tcp_nssock.reset(socket(nsap->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)); if (statp->tcp_nssock < 0) { *terrno = errno; PLOG(DEBUG) << __func__ << ": socket(vc): "; switch (errno) { case EPROTONOSUPPORT: case EPFNOSUPPORT: case EAFNOSUPPORT: PLOG(DEBUG) << __func__ << ": socket(vc): "; return 0; default: *terrno = errno; PLOG(DEBUG) << __func__ << ": socket(vc): "; return -1; } } Loading Loading @@ -831,6 +836,7 @@ read_len: *delay = res_stats_calculate_rtt(&done, &start_time); *rcode = anhp->rcode; } *terrno = 0; return (resplen); } Loading Loading @@ -972,6 +978,7 @@ static int send_dg(res_state statp, res_params* params, const uint8_t* buf, int // It should never happen, but just in case. if (*ns >= statp->nsaddrs.size()) { LOG(ERROR) << __func__ << ": Out-of-bound indexing: " << ns; *terrno = EINVAL; return -1; } Loading @@ -984,15 +991,14 @@ static int send_dg(res_state statp, res_params* params, const uint8_t* buf, int if (statp->nssocks[*ns] == -1) { statp->nssocks[*ns].reset(socket(nsap->sa_family, SOCK_DGRAM | SOCK_CLOEXEC, 0)); if (statp->nssocks[*ns] < 0) { *terrno = errno; PLOG(DEBUG) << __func__ << ": socket(dg): "; switch (errno) { case EPROTONOSUPPORT: case EPFNOSUPPORT: case EAFNOSUPPORT: PLOG(DEBUG) << __func__ << ": socket(dg): "; return (0); default: *terrno = errno; PLOG(DEBUG) << __func__ << ": socket(dg): "; return (-1); } } Loading @@ -1001,6 +1007,7 @@ static int send_dg(res_state statp, res_params* params, const uint8_t* buf, int if (statp->_mark != MARK_UNSET) { if (setsockopt(statp->nssocks[*ns], SOL_SOCKET, SO_MARK, &(statp->_mark), sizeof(statp->_mark)) < 0) { *terrno = errno; statp->closeSockets(); return -1; } Loading @@ -1010,11 +1017,13 @@ static int send_dg(res_state statp, res_params* params, const uint8_t* buf, int // ICMP port-unreachable error. This way we can detect the absence of // a nameserver without timing out. if (random_bind(statp->nssocks[*ns], nsap->sa_family) < 0) { *terrno = errno; dump_error("bind(dg)", nsap, nsaplen); statp->closeSockets(); return (0); } if (connect(statp->nssocks[*ns], nsap, (socklen_t)nsaplen) < 0) { *terrno = errno; dump_error("connect(dg)", nsap, nsaplen); statp->closeSockets(); return (0); Loading @@ -1022,6 +1031,7 @@ static int send_dg(res_state statp, res_params* params, const uint8_t* buf, int LOG(DEBUG) << __func__ << ": new DG socket"; } if (send(statp->nssocks[*ns], (const char*)buf, (size_t)buflen, 0) != buflen) { *terrno = errno; PLOG(DEBUG) << __func__ << ": send: "; statp->closeSockets(); return 0; Loading @@ -1037,6 +1047,7 @@ static int send_dg(res_state statp, res_params* params, const uint8_t* buf, int if (!result.has_value()) { const bool isTimeout = (result.error().code() == ETIMEDOUT); *rcode = (isTimeout) ? RCODE_TIMEOUT : *rcode; *terrno = (isTimeout) ? ETIMEDOUT : errno; *gotsomewhere = (isTimeout) ? 1 : *gotsomewhere; // Leave the UDP sockets open on timeout so we can keep listening for // a late response from this server while retrying on the next server. Loading @@ -1052,6 +1063,7 @@ static int send_dg(res_state statp, res_params* params, const uint8_t* buf, int int resplen = recvfrom(fd, (char*)ans, (size_t)anssiz, 0, (sockaddr*)(void*)&from, &fromlen); if (resplen <= 0) { *terrno = errno; PLOG(DEBUG) << __func__ << ": recvfrom: "; continue; } Loading Loading @@ -1080,6 +1092,7 @@ static int send_dg(res_state statp, res_params* params, const uint8_t* buf, int res_pquery(ans, (resplen > anssiz) ? anssiz : resplen); // record the error statp->_flags |= RES_F_EDNS0ERR; *terrno = EREMOTEIO; continue; } Loading @@ -1095,6 +1108,7 @@ static int send_dg(res_state statp, res_params* params, const uint8_t* buf, int // To get the rest of answer, // use TCP with same server. LOG(DEBUG) << __func__ << ": truncated answer"; *terrno = E2BIG; *v_circuit = 1; return 1; } Loading @@ -1103,6 +1117,7 @@ static int send_dg(res_state statp, res_params* params, const uint8_t* buf, int *rcode = anhp->rcode; *ns = receivedFromNs; *terrno = 0; return resplen; } if (!needRetry) return 0; Loading
resolv_unit_test.cpp +18 −18 Original line number Diff line number Diff line Loading @@ -668,7 +668,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 0, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, }, { rcode: 255, Loading @@ -679,7 +679,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 1, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, } { rcode: 255, Loading @@ -690,7 +690,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 0, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, }, { rcode: 255, Loading @@ -701,7 +701,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 1, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, }, { rcode: 255, Loading @@ -712,7 +712,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 0, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, }, { rcode: 255, Loading @@ -723,7 +723,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 1, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, } { rcode: 255, Loading @@ -734,7 +734,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 0, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, }, { rcode: 255, Loading @@ -745,7 +745,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 1, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, }, { rcode: 255, Loading @@ -756,7 +756,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 0, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, }, { rcode: 255, Loading @@ -767,7 +767,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 1, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, } { rcode: 255, Loading @@ -778,7 +778,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 0, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, }, { rcode: 255, Loading @@ -789,7 +789,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 1, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, }, { rcode: 255, Loading @@ -800,7 +800,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 0, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, }, { rcode: 255, Loading @@ -811,7 +811,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 1, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, } { rcode: 255, Loading @@ -822,7 +822,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 0, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, }, { rcode: 255, Loading @@ -833,7 +833,7 @@ TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { retry_times: 1, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 110, }, ] } Loading Loading @@ -1026,7 +1026,7 @@ TEST_F(ResolvGetAddrInfoTest, TruncatedResponse) { retry_times: 0, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 7, }, { rcode: 0, Loading Loading @@ -1068,7 +1068,7 @@ TEST_F(ResolvGetAddrInfoTest, TruncatedResponse) { retry_times: 0, dns_server_index: 0, connected: 0, linux_errno: 0, linux_errno: 7, }, { rcode: 0, Loading