bionic dns
res_query.c
res_query.c 的 res_nquery 是执行查询的主函数,查询结果为answer。
int
res_nquery(res_state statp,
const char *name, /* domain name */
int class, int type, /* class and type of query */
u_char *answer, /* buffer to put answer */
int anslen) /* size of answer buffer */
res_mkquery.c
res_mkquery.c 的 res_nmkquery 负责组查询包。
res_stat的statp里设置一些dns option,例如,是否recurse,是否开启dnssec。
data 在正向query场景下可以置NULL。
buf是最终组装好的查询包
int
res_nmkquery(res_state statp,
int op, /* opcode of query */
const char *dname, /* domain name */
int class, int type, /* class and type of query */
const u_char *data, /* resource record data */
int datalen, /* length of data */
const u_char *newrr_in, /* new rr for modify or append */
u_char *buf, /* buffer to put query */
int buflen) /* size of buffer */
res_send.c
res_send.c 的res_nsend负责将查询包送到目标server的socket,并从server的socket获取应答包。
int
res_nsend(res_state statp,
const u_char *buf, int buflen, u_char *ans, int anssiz)
res_nsend 从 statp->nsaddr_list[ns] 取server信息。
以UDP查询为例,调用send_dg发送查询包:
n = send_dg(statp, ¶ms, buf, buflen, ans, anssiz, &terrno,
ns, &v_circuit, &gotsomewhere, &now, &rcode, &delay);
send_dg从ns里取socket,发buf查询包,取回应答包ans
params是一些应答参数,例如等待时间
static int
send_dg(res_state statp, struct __res_params* params,
const u_char *buf, int buflen, u_char *ans, int anssiz,
int *terrno, int ns, int *v_circuit, int *gotsomewhere,
time_t *at, int *rcode, int* delay)
...
s = EXT(statp).nssocks[ns];
...
if (send(s, (const char*)buf, (size_t)buflen, 0) != buflen) {
...
if (sendto(s, (const char*)buf, buflen, 0, nsap, nsaplen) != buflen)
...
resplen = recvfrom(s, (char*)ans, (size_t)anssiz,0,
(struct sockaddr *)(void *)&from, &fromlen);
res_init.c
__res_vinit是初始化读取一些系统resolver列表,放到statp里。
如果#ifdef USELOOPBACK为true,会先把loopback的v4, v6地址添加到res_sockaddr_union u数组里,再调res_setservers放到statp里。
然后是读取环境变量,resolv.conf之类的操作,同样添到statp里。
int
__res_vinit(res_state statp, int preinit)
...
res_setservers(statp, u, nserv);
getaddrinfo.c
querybuf的hdr即为包头,buf即为dns包内容,注意hdr与buf的起始地址相同,内存是共用的。
typedef union {
HEADER hdr;
u_char buf[MAXPACKET];
} querybuf;
static struct addrinfo *
getanswer(const querybuf *answer, int anslen, const char *qname, int qtype, const struct addrinfo *pai)