Dns res_query不在res_init之后,将取消设置 请考虑这个代码,我在这里调用 ReSimIn()/Case>,并设置192.1681.77作为唯一的名称服务器。然而,当运行res_query时,显然它正在重新执行res_init,并从resolv.conf返回前3个名称服务器 #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); }
虽然我看到的交通量是8.8.8.8 warm.cDns res_query不在res_init之后,将取消设置 请考虑这个代码,我在这里调用 ReSimIn()/Case>,并设置192.1681.77作为唯一的名称服务器。然而,当运行res_query时,显然它正在重新执行res_init,并从resolv.conf返回前3个名称服务器 #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); },dns,debian,glibc,resolve,Dns,Debian,Glibc,Resolve,虽然我看到的交通量是8.8.8.8 warm.c #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 m
#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];
u_char warm_buf[4096];
char dispbuf[4096];
//char nameserver[] = "127.0.0.1";
//char nameserver[] = "192.168.1.166";
char *nameserver = argv[2];
ns_msg msg;
ns_rr rr;
int i, j, l;
if (argc < 2) {
printf ("Usage: %s <domain>[...]\n", argv[0]);
exit (1);
}
char str[INET_ADDRSTRLEN];
//res_init();
printf("PACKETSZ: %d\n",PACKETSZ);
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);
}
int queryLen = res_mkquery(
ns_o_query, /* regular query */
argv[1], /* the domain to look up */
ns_c_any, /* Internet type */
ns_t_a, /* Look up an A record */
(u_char *)NULL, /* always NULL */
0, /* length of NULL */
(u_char *)NULL, /* always NULL */
warm_buf,/* buffer for the query */
sizeof(warm_buf)); /* size of the buffer */
printf("queryLen is %d\n" , queryLen);
//printf("queryLen is %d\n" , strlen(warm_buf) );
// set to use 192.168.1.77 as nameserver
printf("setting %s as nameserver\n", nameserver);
_res.nscount = 1;
_res.nsaddr_list[0].sin_family = AF_INET;
_res.nsaddr_list[0].sin_addr.s_addr = inet_addr(nameserver);
_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(" -------------------------- >>> l is %d\n", l);
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);
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{
u_char nsbuf[4096];
u_char warm_buf[4096];
char dispbuf[4096];
//char nameserver[]=“127.0.0.1”;
//char nameserver[]=“192.168.1.166”;
char*nameserver=argv[2];
味精;
ns_rr;
int i,j,l;
如果(argc<2){
printf(“用法:%s[…]\n”,argv[0]);
出口(1);
}
char str[INET_ADDRSTRLEN];
//res_init();
printf(“PACKETSZ:%d\n”,PACKETSZ);
对于(int i=0;i<\u res.nscount;i++){
网络地址(AF_inet,&(_res.nsaddr_list[i].sin_addr.s_addr),str,网络地址trlen);
printf(“之前:名称服务器%d:%s\n”,i,str);
}
int queryLen=res\u mkquery(
ns_o_查询,/*常规查询*/
argv[1],/*要查找的域*/
ns_c_any,/*互联网类型*/
N\u t\u a,/*查找a记录*/
(u_char*)NULL,/*始终为NULL*/
0,/*长度为NULL*/
(u_char*)NULL,/*始终为NULL*/
查询的warm_buf、/*缓冲区*/
sizeof(warm_buf));/*缓冲区的大小*/
printf(“queryLen是%d\n”,queryLen);
//printf(“queryLen是%d\n”,strlen(warm_buf));
//设置为使用192.168.1.77作为名称服务器
printf(“将%s设置为名称服务器\n”,名称服务器);
_res.nscount=1;
_res.nsaddr\u list[0]。sin\u family=AF\u INET;
_res.nsaddr\u list[0]。sin\u addr.s\u addr=inet\u addr(名称服务器);
_res.nsaddr_list[0].sin_port=htons(53);
对于(int i=0;i<\u res.nscount;i++){
网络地址(AF_inet,&(_res.nsaddr_list[i].sin_addr.s_addr),str,网络地址trlen);
printf(“之后:名称服务器%d:%s\n”,i,str);
}
对于(i=1;i>l是%d\n”,l);
printf(“res\u查询%d\n后的ns计数,\u res.nscount”);
对于(int i=0;i<\u res.nscount;i++){
网络地址(AF_inet,&(_res.nsaddr_list[i].sin_addr.s_addr),str,网络地址trlen);
printf(“在resu查询之后:名称服务器%d:%s\n”,i,str);
}
if(l<0){
perror(argv[i]);
}否则{
ns_initparse(nsbuf、l和msg);
printf(“--------------\n%s:\n”,argv[i]);
l=ns_msg_计数(msg,ns_s_an);
对于(j=0;j
Debian 9(stretch)和早期版本使用。按照编写此修补程序的方式,缓存仅在调用内部\u res\u init
函数时更新,而res\u init
函数不起作用。这意味着调用实际的解析器函数(例如res\u query
)会导致\uu res\u可能\u init
中的冷缓存,发生重新加载,并丢弃对\u res
的更改
上游执行。上游方法非常不同,它试图通过应用程序处理\u res
补丁:
- 有一个统一的缓存,调用
更新它res\u init
- 如果需要重新加载
,glibc会检查/etc/resolv.conf
值是否仍然反映先前从\u res
加载的内容,如果值不同,则不会应用新的/etc/resolv.conf
内容,也不会覆盖当前的/etc/resolv.conf
设置\u res
- 有一个新的
/RES_NORELOAD
解析器选项,可完全禁用自动重新加载NORELOAD
如果您不想升级glibc,那么如果您在修补
\u res
之前触发对\u res\u-init
的调用,而不是调用res\u-init
,则可以大大降低特定于Debian的重新加载代码覆盖您的更改的可能性。不发送查询的一种方法是使用一些伪参数调用res\mkquery
。这将预热缓存,并且只有在磁盘上的/etc/resolv.conf
文件发生更改时才会重新加载(此时您的更改仍将被覆盖——我认为没有办法防止旧Debian版本出现这种情况)。raspbian,是的,Debian<代码>$ldd bugme linux vdso.so.1(0x7ef2b000)/usr/lib/arm-linux-gnueabihf/libarmmem.so(0x76ed2000)libresolv.so.2=>/lib/arm-linux-gnueabihf/libresolv.so.2(0x76ead000)libc.so.6=>/lib/arm-linux-gnueabihf/libc.so.6(0x76d600)/lib/ld-linux-armhf.so.3(0x76ee8000)。glibc版本,gnu-get\u-libc\u-version()
表示2.24
。谢谢
$ 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
#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];
u_char warm_buf[4096];
char dispbuf[4096];
//char nameserver[] = "127.0.0.1";
//char nameserver[] = "192.168.1.166";
char *nameserver = argv[2];
ns_msg msg;
ns_rr rr;
int i, j, l;
if (argc < 2) {
printf ("Usage: %s <domain>[...]\n", argv[0]);
exit (1);
}
char str[INET_ADDRSTRLEN];
//res_init();
printf("PACKETSZ: %d\n",PACKETSZ);
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);
}
int queryLen = res_mkquery(
ns_o_query, /* regular query */
argv[1], /* the domain to look up */
ns_c_any, /* Internet type */
ns_t_a, /* Look up an A record */
(u_char *)NULL, /* always NULL */
0, /* length of NULL */
(u_char *)NULL, /* always NULL */
warm_buf,/* buffer for the query */
sizeof(warm_buf)); /* size of the buffer */
printf("queryLen is %d\n" , queryLen);
//printf("queryLen is %d\n" , strlen(warm_buf) );
// set to use 192.168.1.77 as nameserver
printf("setting %s as nameserver\n", nameserver);
_res.nscount = 1;
_res.nsaddr_list[0].sin_family = AF_INET;
_res.nsaddr_list[0].sin_addr.s_addr = inet_addr(nameserver);
_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(" -------------------------- >>> l is %d\n", l);
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);
}