响应udp请求

在调用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
                                    }
                        }                         
                    }
                }   
				    
            }
        }		  
					  
					  
				     
    }
}

 

你可能感兴趣的:(bind源码分析,dns,cdn)