android dns之dns服务器可用性机制,成功率低于门限则惩罚抑制(一)

1 dns服务器可用性检测

1.1 send dns请求前,所有dns server是否可用,可用性结果保存到usable_servers[]。

bionic\libc\dns\resolv\res_send.c

int
res_nsend(res_state statp,
	  const u_char *buf, int buflen, u_char *ans, int anssiz)
{
......
	    bool usable_servers[MAXNS];
	    android_net_res_stats_get_usable_servers(&params, stats, statp->nscount,
		    usable_servers);

	    for (ns = 0; ns < statp->nscount; ns++) {
		if (!usable_servers[ns]) continue;

1.2 通过_res_stats_usable_server遍历检查每个DNS server的可用性。如果检测为都不可用,则调整为都可用。

bionic\libc\dns\resolv\res_stats.c

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]);
        if (usable) {
            ++usable_servers_found;
        }
        usable_servers[ns] = usable;
    }
    // If there are no usable servers, consider all of them usable.
    // TODO: Explore other possibilities, such as enabling only the best N servers, etc.
    if (usable_servers_found == 0) {
        for (int ns = 0; ns < nscount; ns++) {
            usable_servers[ns] = true;
        }
    }
}

1.3 _res_stats_usable_server检查

1.3.1 dns全局cache链_res_cache_list,一张网络netid对应一个链节点Cache,含该网络的dns统计__res_stats(最大4个NS的统计)

// Head of the list of caches.  Protected by _res_cache_list_lock.
static struct resolv_cache_info _res_cache_list;

struct resolv_cache_info {
    unsigned                    netid;
    Cache*                      cache;
    struct resolv_cache_info*   next;
    int                         nscount;
    char*                       nameservers[MAXNS];
    struct addrinfo*            nsaddrinfo[MAXNS];
    int                         revision_id; // # times the nameservers have been replaced
    struct __res_params         params;
    struct __res_stats          nsstats[MAXNS];
    char                        defdname[MAXDNSRCHPATH];
    int                         dnsrch_offset[MAXDNSRCH+1];  // offsets into defdname
/*AR000AT6PU liuheng 00308202 20180720 begin */
    bool                       isipv6optimizationopen;
    int                         ipv6timeout;
    unsigned                 iptype;// ipaddrtype ipv4,ipv6 or ipv4v6
    int                         servicetype;
    unsigned                 ipv6domainblacklistcount;
    char*                     domainblacklist[IPV6MAXBLACKLISTLEN];
/*AR000AT6PU liuheng 00308202 20180720 end */
};

1.3.1 dns参数(含惩罚门限)

1.3.1.1 成功率门限75% SUCCESS_THRESHOLD 75
1.3.1.2 默认sample有效期1800秒 #define NSSAMPLE_VALIDITY 1800
/* Hard-coded defines */
#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
					 * this value, the server is considered failing
					 */
#define NSSAMPLE_VALIDITY	1800	/* Sample validity in seconds.
					 * Set to -1 to disable skipping failing
					 * servers.
					 */

/* If EDNS0_PADDING is defined, queries will be padded to a multiple of this length
when EDNS0 is active. */
#define EDNS0_PADDING	128

/* per-netid configuration parameters passed from netd to the resolver */
struct __res_params {
    uint16_t sample_validity; // sample lifetime in s
    // threshold of success / total samples below which a server is considered broken
    uint8_t success_threshold; // 0: disable, value / 100 otherwise
    uint8_t min_samples; // min # samples needed for statistics to be considered meaningful
    uint8_t max_samples; // max # samples taken into account for statistics
};

1.3.2 dns server可用性统计参数

bionic\libc\dns\include\resolv_stats.h
__res_stats,针对一个dns server的统计,记录了最近sample_count个dns请求记录的时延等结果

#define RCODE_INTERNAL_ERROR    254
#define RCODE_TIMEOUT           255

/*
 * Resolver reachability statistics and run-time parameters.
 */

struct __res_sample {
    time_t			at;    // time in s at which the sample was recorded
    uint16_t			rtt;   // round-trip time in ms
    uint8_t			rcode; // the DNS rcode or RCODE_XXX defined above
};

struct __res_stats {
    // Stats of the last <sample_count> queries.
    struct __res_sample		samples[MAXNSSAMPLES];
    // The number of samples stored.
    uint8_t			sample_count;
    // The next sample to modify.
    uint8_t			sample_next; //下一个sample将存放到数组里的索引
};
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值