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); }

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); },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

虽然我看到的交通量是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 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
    更新它
  • 如果需要重新加载
    /etc/resolv.conf
    ,glibc会检查
    \u res
    值是否仍然反映先前从
    /etc/resolv.conf
    加载的内容,如果值不同,则不会应用新的
    /etc/resolv.conf
    内容,也不会覆盖当前的
    \u res
    设置
  • 有一个新的
    RES_NORELOAD
    /
    NORELOAD
    解析器选项,可完全禁用自动重新加载
这些更改将是即将发布的Debian版本10(buster)的一部分


如果您不想升级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);
}