DO NOT MERGE Add new info functions to resolver for use by Netd.
android_net_res_stats_get_info_for_net returns the current name servers, search domains, parameters and stats for the given network ID. android_net_res_stats_aggregate provides statistics such as errors counts from the raw stats data reported by android_net_res_stats_get_info_for_net. android_net_res_stats_get_usable_servers uses the data returned by android_net_res_stats_aggregate to determine which of the servers are considered valid or broken by the resolver. BUG: 25731675 Change-Id: I6059b68e5e8b809027a4d3135f6081588bee8a7d
This commit is contained in:
parent
589afca92c
commit
21bf063727
|
@ -20,8 +20,10 @@
|
|||
#include <stdint.h>
|
||||
|
||||
/* Hard-coded defines */
|
||||
#define MAXNS 4 /* max # name servers we'll track */
|
||||
#define MAXNSSAMPLES 64 /* max # samples to store per server */
|
||||
#define MAXNS 4 /* max # name servers we'll track */
|
||||
#define MAXDNSRCH 6 /* max # domains in search path */
|
||||
#define MAXDNSRCHPATH 256 /* max length of domain search paths */
|
||||
#define MAXNSSAMPLES 64 /* max # samples to store per server */
|
||||
|
||||
/* Defaults used for initializing __res_params */
|
||||
#define SUCCESS_THRESHOLD 75 /* if successes * 100 / total_samples is less than
|
||||
|
|
|
@ -140,7 +140,6 @@ struct res_sym {
|
|||
* Global defines and variables for resolver stub.
|
||||
*/
|
||||
#define MAXDFLSRCH 3 /* # default domain levels to try */
|
||||
#define MAXDNSRCH 6 /* max # domains in search path */
|
||||
#define LOCALDOMAINPARTS 2 /* min levels in name that is "local" */
|
||||
|
||||
#define RES_TIMEOUT 5 /* min. seconds between retries */
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#ifndef _RES_STATS_H
|
||||
#define _RES_STATS_H
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
@ -46,18 +47,13 @@ struct __res_stats {
|
|||
};
|
||||
|
||||
/* Calculate the round-trip-time from start time t0 and end time t1. */
|
||||
int
|
||||
extern int
|
||||
_res_stats_calculate_rtt(const struct timespec* t1, const struct timespec* t0);
|
||||
|
||||
/* Initialize a sample for calculating server reachability statistics. */
|
||||
extern void
|
||||
_res_stats_set_sample(struct __res_sample* sample, time_t now, int rcode, int rtt);
|
||||
|
||||
/* Aggregates the reachability statistics for the given server based on on the stored samples. */
|
||||
extern void
|
||||
_res_stats_aggregate(struct __res_stats* stats, int* successes, int* errors, int* timeouts,
|
||||
int* internal_errors, int* rtt_avg, time_t* last_sample_time);
|
||||
|
||||
/* Returns true if the server is considered unusable, i.e. if the success rate is not lower than the
|
||||
* threshold for the stored stored samples. If not enough samples are stored, the server is
|
||||
* considered usable.
|
||||
|
@ -65,9 +61,24 @@ _res_stats_aggregate(struct __res_stats* stats, int* successes, int* errors, int
|
|||
extern bool
|
||||
_res_stats_usable_server(const struct __res_params* params, struct __res_stats* stats);
|
||||
|
||||
__BEGIN_DECLS
|
||||
/* Aggregates the reachability statistics for the given server based on on the stored samples. */
|
||||
extern void
|
||||
android_net_res_stats_aggregate(struct __res_stats* stats, int* successes, int* errors,
|
||||
int* timeouts, int* internal_errors, int* rtt_avg, time_t* last_sample_time)
|
||||
__attribute__((visibility ("default")));
|
||||
|
||||
extern int
|
||||
android_net_res_stats_get_info_for_net(unsigned netid, int* nscount,
|
||||
struct sockaddr_storage servers[MAXNS], int* dcount, char domains[MAXDNSRCH][MAXDNSRCHPATH],
|
||||
struct __res_params* params, struct __res_stats stats[MAXNS])
|
||||
__attribute__((visibility ("default")));
|
||||
|
||||
/* Returns an array of bools indicating which servers are considered good */
|
||||
extern void
|
||||
_res_stats_get_usable_servers(const struct __res_params* params, struct __res_stats stats[],
|
||||
int nscount, bool valid_servers[]);
|
||||
android_net_res_stats_get_usable_servers(const struct __res_params* params,
|
||||
struct __res_stats stats[], int nscount, bool valid_servers[])
|
||||
__attribute__((visibility ("default")));
|
||||
__END_DECLS
|
||||
|
||||
#endif // _RES_STATS_H
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
*/
|
||||
|
||||
#include "resolv_cache.h"
|
||||
|
||||
#include <resolv.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
@ -1238,8 +1239,7 @@ struct resolv_cache_info {
|
|||
int revision_id; // # times the nameservers have been replaced
|
||||
struct __res_params params;
|
||||
struct __res_stats nsstats[MAXNS];
|
||||
// TODO: replace with char* defdname[MAXDNSRCH]
|
||||
char defdname[256];
|
||||
char defdname[MAXDNSRCHPATH];
|
||||
int dnsrch_offset[MAXDNSRCH+1]; // offsets into defdname
|
||||
};
|
||||
|
||||
|
@ -2182,6 +2182,68 @@ _res_cache_clear_stats_locked(struct resolv_cache_info* cache_info) {
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
android_net_res_stats_get_info_for_net(unsigned netid, int* nscount,
|
||||
struct sockaddr_storage servers[MAXNS], int* dcount, char domains[MAXDNSRCH][MAXDNSRCHPATH],
|
||||
struct __res_params* params, struct __res_stats stats[MAXNS]) {
|
||||
int revision_id = -1;
|
||||
pthread_mutex_lock(&_res_cache_list_lock);
|
||||
|
||||
struct resolv_cache_info* info = _find_cache_info_locked(netid);
|
||||
if (info) {
|
||||
if (info->nscount > MAXNS) {
|
||||
pthread_mutex_unlock(&_res_cache_list_lock);
|
||||
XLOG("%s: nscount %d > MAXNS %d", __FUNCTION__, info->nscount, MAXNS);
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < info->nscount; i++) {
|
||||
// Verify that the following assumptions are held, failure indicates corruption:
|
||||
// - getaddrinfo() may never return a sockaddr > sockaddr_storage
|
||||
// - all addresses are valid
|
||||
// - there is only one address per addrinfo thanks to numeric resolution
|
||||
int addrlen = info->nsaddrinfo[i]->ai_addrlen;
|
||||
if (addrlen < (int) sizeof(struct sockaddr) ||
|
||||
addrlen > (int) sizeof(servers[0])) {
|
||||
pthread_mutex_unlock(&_res_cache_list_lock);
|
||||
XLOG("%s: nsaddrinfo[%d].ai_addrlen == %d", __FUNCTION__, i, addrlen);
|
||||
errno = EMSGSIZE;
|
||||
return -1;
|
||||
}
|
||||
if (info->nsaddrinfo[i]->ai_addr == NULL) {
|
||||
pthread_mutex_unlock(&_res_cache_list_lock);
|
||||
XLOG("%s: nsaddrinfo[%d].ai_addr == NULL", __FUNCTION__, i);
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
if (info->nsaddrinfo[i]->ai_next != NULL) {
|
||||
pthread_mutex_unlock(&_res_cache_list_lock);
|
||||
XLOG("%s: nsaddrinfo[%d].ai_next != NULL", __FUNCTION__, i);
|
||||
errno = ENOTUNIQ;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
*nscount = info->nscount;
|
||||
for (i = 0; i < info->nscount; i++) {
|
||||
memcpy(&servers[i], info->nsaddrinfo[i]->ai_addr, info->nsaddrinfo[i]->ai_addrlen);
|
||||
stats[i] = info->nsstats[i];
|
||||
}
|
||||
for (i = 0; i < MAXDNSRCH; i++) {
|
||||
if (info->dnsrch_offset[i] == -1) {
|
||||
break;
|
||||
}
|
||||
strlcpy(domains[i], info->defdname + info->dnsrch_offset[i], MAXDNSRCHPATH);
|
||||
}
|
||||
*dcount = i;
|
||||
*params = info->params;
|
||||
revision_id = info->revision_id;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&_res_cache_list_lock);
|
||||
return revision_id;
|
||||
}
|
||||
|
||||
int
|
||||
_resolv_cache_get_resolver_stats( unsigned netid, struct __res_params* params,
|
||||
struct __res_stats stats[MAXNS]) {
|
||||
|
|
|
@ -492,7 +492,8 @@ res_nsend(res_state statp,
|
|||
struct __res_params params;
|
||||
int revision_id = _resolv_cache_get_resolver_stats(statp->netid, ¶ms, stats);
|
||||
bool usable_servers[MAXNS];
|
||||
_res_stats_get_usable_servers(¶ms, stats, statp->nscount, usable_servers);
|
||||
android_net_res_stats_get_usable_servers(¶ms, stats, statp->nscount,
|
||||
usable_servers);
|
||||
|
||||
for (ns = 0; ns < statp->nscount; ns++) {
|
||||
if (!usable_servers[ns]) continue;
|
||||
|
|
|
@ -54,8 +54,8 @@ _res_stats_clear_samples(struct __res_stats* stats)
|
|||
|
||||
/* Aggregates the reachability statistics for the given server based on on the stored samples. */
|
||||
void
|
||||
_res_stats_aggregate(struct __res_stats* stats, int* successes, int* errors, int* timeouts,
|
||||
int* internal_errors, int* rtt_avg, time_t* last_sample_time)
|
||||
android_net_res_stats_aggregate(struct __res_stats* stats, int* successes, int* errors,
|
||||
int* timeouts, int* internal_errors, int* rtt_avg, time_t* last_sample_time)
|
||||
{
|
||||
int s = 0; // successes
|
||||
int e = 0; // errors
|
||||
|
@ -123,8 +123,8 @@ _res_stats_usable_server(const struct __res_params* params, struct __res_stats*
|
|||
int internal_errors = -1;
|
||||
int rtt_avg = -1;
|
||||
time_t last_sample_time = 0;
|
||||
_res_stats_aggregate(stats, &successes, &errors, &timeouts, &internal_errors, &rtt_avg,
|
||||
&last_sample_time);
|
||||
android_net_res_stats_aggregate(stats, &successes, &errors, &timeouts, &internal_errors,
|
||||
&rtt_avg, &last_sample_time);
|
||||
if (successes >= 0 && errors >= 0 && timeouts >= 0) {
|
||||
int total = successes + errors + timeouts;
|
||||
if (DBG) {
|
||||
|
@ -164,8 +164,8 @@ _res_stats_usable_server(const struct __res_params* params, struct __res_stats*
|
|||
}
|
||||
|
||||
void
|
||||
_res_stats_get_usable_servers(const struct __res_params* params, struct __res_stats stats[],
|
||||
int nscount, bool usable_servers[]) {
|
||||
android_net_res_stats_get_usable_servers(const struct __res_params* params,
|
||||
struct __res_stats stats[], int nscount, bool usable_servers[]) {
|
||||
unsigned usable_servers_found = 0;
|
||||
for (int ns = 0; ns < nscount; ns++) {
|
||||
bool usable = _res_stats_usable_server(params, &stats[ns]);
|
||||
|
|
|
@ -1449,3 +1449,10 @@ LIBC_PRIVATE {
|
|||
SHA1Transform; # arm x86 mips
|
||||
SHA1Update; # arm x86 mips
|
||||
} LIBC_N;
|
||||
|
||||
LIBC_PLATFORM {
|
||||
global:
|
||||
android_net_res_stats_get_info_for_net;
|
||||
android_net_res_stats_aggregate;
|
||||
android_net_res_stats_get_usable_servers;
|
||||
} LIBC_N;
|
||||
|
|
|
@ -1488,3 +1488,10 @@ LIBC_PRIVATE {
|
|||
wait3; # arm x86 mips nobrillo
|
||||
wcswcs; # arm x86 mips nobrillo
|
||||
} LIBC_N;
|
||||
|
||||
LIBC_PLATFORM {
|
||||
global:
|
||||
android_net_res_stats_get_info_for_net;
|
||||
android_net_res_stats_aggregate;
|
||||
android_net_res_stats_get_usable_servers;
|
||||
} LIBC_N;
|
||||
|
|
|
@ -1203,3 +1203,10 @@ LIBC_PRIVATE {
|
|||
get_malloc_leak_info;
|
||||
gMallocLeakZygoteChild;
|
||||
} LIBC_N;
|
||||
|
||||
LIBC_PLATFORM {
|
||||
global:
|
||||
android_net_res_stats_get_info_for_net;
|
||||
android_net_res_stats_aggregate;
|
||||
android_net_res_stats_get_usable_servers;
|
||||
} LIBC_N;
|
||||
|
|
|
@ -1514,3 +1514,10 @@ LIBC_PRIVATE {
|
|||
wait3; # arm x86 mips nobrillo
|
||||
wcswcs; # arm x86 mips nobrillo
|
||||
} LIBC_N;
|
||||
|
||||
LIBC_PLATFORM {
|
||||
global:
|
||||
android_net_res_stats_get_info_for_net;
|
||||
android_net_res_stats_aggregate;
|
||||
android_net_res_stats_get_usable_servers;
|
||||
} LIBC_N;
|
||||
|
|
|
@ -1290,3 +1290,10 @@ LIBC_PRIVATE {
|
|||
SHA1Transform; # arm x86 mips
|
||||
SHA1Update; # arm x86 mips
|
||||
} LIBC_N;
|
||||
|
||||
LIBC_PLATFORM {
|
||||
global:
|
||||
android_net_res_stats_get_info_for_net;
|
||||
android_net_res_stats_aggregate;
|
||||
android_net_res_stats_get_usable_servers;
|
||||
} LIBC_N;
|
||||
|
|
|
@ -1329,3 +1329,10 @@ LIBC_PRIVATE {
|
|||
wait3; # arm x86 mips nobrillo
|
||||
wcswcs; # arm x86 mips nobrillo
|
||||
} LIBC_N;
|
||||
|
||||
LIBC_PLATFORM {
|
||||
global:
|
||||
android_net_res_stats_get_info_for_net;
|
||||
android_net_res_stats_aggregate;
|
||||
android_net_res_stats_get_usable_servers;
|
||||
} LIBC_N;
|
||||
|
|
|
@ -1203,3 +1203,10 @@ LIBC_PRIVATE {
|
|||
get_malloc_leak_info;
|
||||
gMallocLeakZygoteChild;
|
||||
} LIBC_N;
|
||||
|
||||
LIBC_PLATFORM {
|
||||
global:
|
||||
android_net_res_stats_get_info_for_net;
|
||||
android_net_res_stats_aggregate;
|
||||
android_net_res_stats_get_usable_servers;
|
||||
} LIBC_N;
|
||||
|
|
|
@ -1289,3 +1289,10 @@ LIBC_PRIVATE {
|
|||
SHA1Transform; # arm x86 mips
|
||||
SHA1Update; # arm x86 mips
|
||||
} LIBC_N;
|
||||
|
||||
LIBC_PLATFORM {
|
||||
global:
|
||||
android_net_res_stats_get_info_for_net;
|
||||
android_net_res_stats_aggregate;
|
||||
android_net_res_stats_get_usable_servers;
|
||||
} LIBC_N;
|
||||
|
|
|
@ -1328,3 +1328,10 @@ LIBC_PRIVATE {
|
|||
wait3; # arm x86 mips nobrillo
|
||||
wcswcs; # arm x86 mips nobrillo
|
||||
} LIBC_N;
|
||||
|
||||
LIBC_PLATFORM {
|
||||
global:
|
||||
android_net_res_stats_get_info_for_net;
|
||||
android_net_res_stats_aggregate;
|
||||
android_net_res_stats_get_usable_servers;
|
||||
} LIBC_N;
|
||||
|
|
|
@ -1203,3 +1203,10 @@ LIBC_PRIVATE {
|
|||
get_malloc_leak_info;
|
||||
gMallocLeakZygoteChild;
|
||||
} LIBC_N;
|
||||
|
||||
LIBC_PLATFORM {
|
||||
global:
|
||||
android_net_res_stats_get_info_for_net;
|
||||
android_net_res_stats_aggregate;
|
||||
android_net_res_stats_get_usable_servers;
|
||||
} LIBC_N;
|
||||
|
|
Loading…
Reference in New Issue