在调用query_find查找到相应的数据以后,开始响应该请求了,具体调用的函数是query_send
query_send(ns_client_t *client, query_log_t* q_log)
{
dump_answer(client, q_log);
{
//设置响应头
}
ns_client_send(client);
{
//确定类型
if (client->view != NULL)
{
if (client->view->preferred_glue == dns_rdatatype_a)
preferred_glue = DNS_MESSAGERENDER_PREFER_A;
else if (client->view->preferred_glue == dns_rdatatype_aaaa)
preferred_glue = DNS_MESSAGERENDER_PREFER_AAAA;
}
//申请buffer
result = client_allocsendbuf(client, &buffer, &tcpbuffer, 0,sendbuf, &data);
//确认好压缩方式
result = dns_compress_init(&cctx, -1, client->mctx);
//设置好响应中的question,answer,authority,addition四个字段
result = dns_message_rendersection(client->message, DNS_SECTION_QUESTION, 0);
result = dns_message_rendersection(client->message, DNS_SECTION_ANSWER,
result = dns_message_rendersection(client->message, DNS_SECTION_AUTHORITY,
result = dns_message_rendersection(client->message,DNS_SECTION_ADDITIONAL,
//封装好以后进行包的发送
if (TCP_CLIENT(client))
{
result = client_sendpkg(client, &tcpbuffer);
}
else
{
result = client_sendpkg(client, &buffer);
{
//通过client获得socket和address的信息
if (TCP_CLIENT(client))
{
socket = client->tcpsocket;
address = NULL;
}
else
{
socket = client->udpsocket;
address = &client->peeraddr;
//转换地址为网络地址
isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
}
//统一调用该函数进行发送
result = isc_socket_sendto2(socket, &r, client->task,address, pktinfo,client->sendevent, sockflags);
{
//设置好event的一些内容,ev_sender设置为sock
return (socket_send(sock, event, task, address, pktinfo, flags));
{
//修改isc_socketevent_t类型的socketevent的ev_sender
dev->ev_sender = task;
//设置dev的address
set_dev_address(address, sock, dev);
//udp的话直接send,tcp的话注意前面还没有把该socket加入到watcher线程中监控,所以这里第一次发送的时候需要先添加一次
if (sock->type == isc_sockettype_udp)
io_state = doio_send(sock, dev);
else
{
if (ISC_LIST_EMPTY(sock->send_list))
io_state = doio_send(sock, dev);
else
io_state = DOIO_SOFT;
}
switch(io_state)
{
case DOIO_SOFT:
//把该socket加入到watcher线程中,且监控可写状态
if (ISC_LIST_EMPTY(sock->send_list))
select_poke(sock->manager, sock->fd,SELECT_POKE_WRITE);
ISC_LIST_ENQUEUE(sock->send_list, dev, ev_link);
case DOIO_HARD:
case DOIO_SUCCESS:
if ((flags & ISC_SOCKFLAG_IMMEDIATE) == 0)
send_senddone_event(sock, &dev);
{
task = (*dev)->ev_sender;
(*dev)->ev_sender = sock;
if (ISC_LINK_LINKED(*dev, ev_link))
ISC_LIST_DEQUEUE(sock->send_list, *dev, ev_link);
//发送事件
isc_task_sendanddetach
}
}
}
}
}
}
}
}