请考虑以下代码,我在这里致电ClickableSpan yourstringClick2 = new ClickableSpan() {
@Override
public void onClick(View view) {
openyourdialoghere()
}
};
makeLinks(tvLink, new String[]{"your string","your string 2"}, new ClickableSpan[]{
yourstringClick,yourStringClick2
});
,并将192.168.1.77设置为唯一的名称服务器。但是,当res_init()
运行时,显然是在重新执行res_init,然后从resolv.conf返回到前三个名称服务器。
res_query
下面是我们可以看到这种情况的输出:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <resolv.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main (int argc, char *argv[])
{
u_char nsbuf[4096];
char dispbuf[4096];
ns_msg msg;
ns_rr rr;
int i, j, l;
if (argc < 2) {
printf ("Usage: %s <domain>[...]\n", argv[0]);
exit (1);
}
res_init();
char str[INET_ADDRSTRLEN];
for (int i = 0 ; i < _res.nscount; i++){
inet_ntop(AF_INET,&(_res.nsaddr_list[i].sin_addr.s_addr) , str, INET_ADDRSTRLEN);
printf("Before: nameserver %d : %s\n", i,str);
}
// set to use 192.168.1.77 as nameserver
_res.nscount = 1;
_res.nsaddr_list[0].sin_family = AF_INET;
_res.nsaddr_list[0].sin_addr.s_addr = inet_addr("192.168.1.77");
_res.nsaddr_list[0].sin_port = htons(53);
for (int i = 0 ; i < _res.nscount; i++){
inet_ntop(AF_INET,&(_res.nsaddr_list[i].sin_addr.s_addr) , str, INET_ADDRSTRLEN);
printf("After: nameserver %d : %s\n", i,str);
}
for (i = 1; i < argc; i++) {
printf("ns count before res_query %d\n", _res.nscount);
l = res_query (argv[i], ns_c_any, ns_t_a, nsbuf, sizeof (nsbuf));
printf("ns count after res_query %d\n", _res.nscount);
for (int i = 0 ; i < _res.nscount; i++){
inet_ntop(AF_INET,&(_res.nsaddr_list[i].sin_addr.s_addr) , str, INET_ADDRSTRLEN);
printf("After res_query: nameserver %d : %s\n", i,str);
}
if (l < 0) {
perror (argv[i]);
} else {
ns_initparse (nsbuf, l, &msg);
printf ("---------------------\n%s :\n", argv[i]);
l = ns_msg_count (msg, ns_s_an);
for (j = 0; j < l; j++) {
ns_parserr (&msg, ns_s_an, j, &rr);
ns_sprintrr (&msg, &rr, NULL, NULL, dispbuf, sizeof (dispbuf));
printf ("%s\n", dispbuf);
}
}
}
exit (0);
}
我在做什么错?我该怎么做$ ./a.out cnn.com
Before: nameserver 0 : 127.0.0.1
Before: nameserver 1 : 192.168.1.1
Before: nameserver 2 : 1.1.1.1
After: nameserver 0 : 192.168.1.77
ns count before res_query 1
ns count after res_query 3
After res_query: nameserver 0 : 127.0.0.1 /// <----- these...
After res_query: nameserver 1 : 192.168.1.1 /// <----- these...
After res_query: nameserver 2 : 1.1.1.1 /// <----- these...
---------------------
cnn.com :
cnn.com. 58S IN A 151.101.129.67
cnn.com. 58S IN A 151.101.1.67
cnn.com. 58S IN A 151.101.65.67
cnn.com. 58S IN A 151.101.193.67
而又不做另一个res_query
呢?
更新1
感谢您的详尽而彻底的答复。在下面,我将修改为先调用res_init()
然后再调用res_init
后,可以保留添加的名称服务器。
但是,更多的是错过:
res_mkquery()
尽管我看到流量达到8.8.8.8。
warm.c
$ time ./warm cnn.com 8.8.8.8
PACKETSZ: 512
Before: nameserver 0 : 127.0.0.1
Before: nameserver 1 : 192.168.1.1
Before: nameserver 2 : 1.1.1.1
queryLen is 25
setting 8.8.8.8 as nameserver
After: nameserver 0 : 8.8.8.8
ns count before res_query 1
res_query failed!
ns count after res_query 1
After res_query: nameserver 0 : 8.8.8.8
cnn.com: Connection timed out
ns count before res_query 1
res_query failed!
ns count after res_query 1
After res_query: nameserver 0 : 8.8.8.8
8.8.8.8: Connection timed out
real 0m0.131s
user 0m0.008s
sys 0m0.000s
答案 0 :(得分:1)
Debian 9(拉伸)和更早的版本使用custom, downstream-only patch to automatically reload /etc/resolv.conf
if it has changed。编写此补丁的方式只有在调用内部__res_maybe_init
函数时才会更新缓存,而res_init
则不执行。这意味着对实际解析器功能(例如res_query
)的调用会导致__res_maybe_init
中的冷缓存,发生重新加载,并且您对_res
所做的更改将被丢弃。>
上游已实施automatic /etc/resolv.conf
reloading glibc 2.26。上游方法非常不同,它尝试处理应用程序的_res
修补程序:
res_init
会对其进行更新。/etc/resolv.conf
,则glibc会检查_res
的值是否仍然反映了从/etc/resolv.conf
加载的先前值,以及是否值a不同的是,新的/etc/resolv.conf
内容未应用 ,并且当前的_res
设置不会被覆盖。RES_NORELOAD
/ noreload
解析器选项,它会完全禁用自动重新加载。这些更改将成为即将发布的Debian版本10(破坏者)的一部分。
如果您不想升级glibc,则可以在修补__res_maybe_init
之前触发对_res
的调用而不是Debian特定的重载代码覆盖更改的可能性,而不是呼叫res_init
。一种无需发送查询即可执行此操作的方法是使用一些伪参数调用res_mkquery
。这将预热缓存,并且仅在磁盘上更改/etc/resolv.conf
文件时才会重新加载(此时,您的更改仍将被覆盖-我认为无法通过以下方法来防止这种情况:旧的Debian版本)。