Пожалуйста, рассмотрите этот код, где я звоню res_init()
, и установив 192.168.1.77 в качестве единственного сервера имен.Однако, когда res_query
запускается, очевидно, он повторно выполняет res_init и возвращается к первым 3 серверам имен из resolv.conf.
#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
, не делая еще один res_init()
за моей спиной?
Обновление 1
Спасибо за подробный и подробный ответ.Ниже я могу сохранить добавленные мной серверы имен после того, как я изменил их на res_init
, а затем res_mkquery()
.
Однако, это все еще большая ошибка:
$ 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
Хотя я вижу трафик, идущий к 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);
}