bind client.c

来源:互联网 发布:考勤系统源码 编辑:程序博客网 时间:2024/06/06 23:19

整体功能分析

client.c 主要是负责DNS 服务器与用户接口的设置,可以分成三个模块:
1.数据包传送模块
2.用户的创建模块
3.用户管理器的创建模块
用户的创建模块是为用户管理器的创建模块建立的,对于同一用户,他每次建立连接,只要连接不断开和超时,他的用户创建模块不会被再次激发。因此,这两个模块仅是一次性的,在用户创建以后再发送数据包,它们将不会有任何影响。数据包传送模块则是关于数据传输的,每次传送数据包它都会参与其中。
client.h说明

/* This module defines two objects, ns_client_t and ns_clientmgr_t. * * An ns_client_t object handles incoming DNS requests from clients * on a given network interface. * * Each ns_client_t object can handle only one TCP connection or UDP * request at a time.  Therefore, several ns_client_t objects are * typically created to serve each network interface, e.g., one * for handling TCP requests and a few (one per CPU) for handling * UDP requests. * * Incoming requests are classified as queries, zone transfer * requests, update requests, notify requests, etc, and handed off * to the appropriate request handler.  When the request has been * fully handled (which can be much later), the ns_client_t must be * notified of this by calling one of the following functions * exactly once in the context of its task: * \code *   ns_client_send()   (sending a non-error response) *   ns_client_sendraw() (sending a raw response) *   ns_client_error()  (sending an error response) *   ns_client_next()   (sending no response) *\endcode * This will release any resources used by the request and * and allow the ns_client_t to listen for the next request. * * A ns_clientmgr_t manages a number of ns_client_t objects. * New ns_client_t objects are created by calling * ns_clientmgr_createclients(). They are destroyed by * destroying their manager. */

数据结构

/*% nameserver client structure */struct ns_client{    unsigned int        magic;    isc_mem_t *     mctx;    ns_clientmgr_t *    manager;    int         state;    int         newstate;    int         naccepts;    int         nreads;    int         nsends;    int         nrecvs;    int         nupdates;    int         nctls;    int         references;    isc_boolean_t       needshutdown;   /*                         * Used by clienttest to get                         * the client to go from                         * inactive to free state                         * by shutting down the                         * client's task.                         */    unsigned int        attributes;    isc_task_t *        task;    dns_view_t *        view;    dns_dispatch_t *    dispatch;    isc_socket_t *      udpsocket;    isc_socket_t *      tcplistener;    isc_socket_t *      tcpsocket;    unsigned char *     tcpbuf;    dns_tcpmsg_t        tcpmsg;    isc_boolean_t       tcpmsg_valid;    isc_timer_t *       timer;    isc_boolean_t       timerset;    dns_message_t *     message;    isc_socketevent_t * sendevent;    isc_socketevent_t * recvevent;    unsigned char *     recvbuf;    dns_rdataset_t *    opt;    isc_uint16_t        udpsize;    isc_uint16_t        extflags;    isc_int16_t     ednsversion;    /* -1 noedns */    void            (*next)(ns_client_t *);    void            (*shutdown)(void *arg, isc_result_t result);    void            *shutdown_arg;    ns_query_t      query;    isc_stdtime_t       requesttime;    isc_stdtime_t       now;    dns_name_t      signername;   /*%< [T]SIG key name */    dns_name_t *        signer;       /*%< NULL if not valid sig */    isc_boolean_t       mortal;       /*%< Die after handling request */    isc_quota_t     *tcpquota;    isc_quota_t     *recursionquota;    ns_interface_t      *interface;    isc_sockaddr_t      peeraddr;    isc_boolean_t       peeraddr_valid;    struct in6_pktinfo  pktinfo;    isc_event_t     ctlevent;    /*%     * Information about recent FORMERR response(s), for     * FORMERR loop avoidance.  This is separate for each     * client object rather than global only to avoid     * the need for locking.     */    struct {        isc_sockaddr_t      addr;        isc_stdtime_t       time;        dns_messageid_t     id;    } formerrcache;    ISC_LINK(ns_client_t)   link;    /*%     * The list 'link' is part of, or NULL if not on any list.     */    client_list_t       *list;}

函数调用关系

client_create 为建立用户刚模块核心函数

static isc_result_tclient_create(ns_clientmgr_t *manager, ns_client_t **clientp) 

这里写图片描述

这里写图片描述

ns_client_send 为发送数据。

voidns_client_send(ns_client_t *client)

Here is the caller graph for this function:

Here is the caller graph for this function:

sendraw 发送原始请求

voidns_client_sendraw(ns_client_t *client, dns_message_t *message)

这里写图片描述

用户管理器创建用户

isc_result_tns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n,               ns_interface_t *ifp, isc_boolean_t tcp)

这里写图片描述
这里写图片描述

重要函数说明

static isc_boolean_t exit_check(ns_client_t *client)

开检查,针对用户的不同状态,逐级往free 方向递减(即从状态4 至0 一步步减少),只要有一项(如更新、发送、接收)数为0,则返回1,表示用户离开。

voidns_client_next(ns_client_t *client, isc_result_t result)

执行下一请求,当用户为工作或读取状态且上一次请求成功,执行下一请求,否则将失败写于日志中。

static voidclient_senddone(isc_task_t *task, isc_event_t *event)

发送完成,发送完成某一任务、事件。当发送事件不成功,日志记录。当tcp缓存非空(即成功),在内存中记录,若用户离开,则函数中止,否则执行下一请求。调用exit_check,ns_client_next函数。

static isc_result_tclient_allocsendbuf(ns_client_t *client, isc_buffer_t *buffer,                    isc_buffer_t *tcpbuffer, isc_uint32_t length,                    unsigned char *sendbuf, unsigned char **datap)

分配发送缓存,返回分配结果。在client_send,client_sentufraw 中调用。

static isc_result_tclient_sendpkg(ns_client_t *client, isc_buffer_t *buffer) 

发送数据包,根据判断是tcp 还是udp 来将用户的任务发向不同的接口,再对得到的结果进行判断,成功则调用client_senddone函数。返回结果。

1.数据包具体的发送是在socker.c 的isc_send_socket2()和它内部socket_send()函数进行的,client_sendpkg 只是对包进行发送接口的选择,并对结果进行处理。
2.对于不同的操作系统关于socket 的函数是不同的,分成unix 和win32 两类。

voidns_client_recursing(ns_client_t *client)

域名服务器递归:处理用户的表client->list,将用户的连接加到用户管理器的递归表中,在将用户的表等于用户管理器的递归表,实则是为用户起到递归查找域名服务器的作用。

1 0
原创粉丝点击