首页 > 其他 > 详细

BIND9中的UDP数据处理

时间:2014-03-10 04:09:26      阅读:440      评论:0      收藏:0      [点我收藏+]

本文简要介绍一下BIND9中的UDP数据处理,包括如何创建socket、设置什么socket参数、多线程环境中如何让多个线程读取53端口的数据等等。

 

BIND9的架构采用event-driven和task-based。对于像TCP这样的事件采用event-driven来等待读写时间,而在多线程方面,采用task-based的方式,服务器启动时由task_manager创建一系列干活的线程task(CPU个数个),然后外部的用户通过调用isc_task_send函数将事件挂到task_manager的事件队列中,各线程(task)从这个事件队列中获得要干的活,开始干活。

 

对于UDP而言,BIND9的做法是在主进程中创建好UDP socket,然后各个线程都在这个fd上通过recvmsg来收取消息并处理

关键流程如下所示:

1, 主进程ns_interface_listenudp <--ns_interface_setup <-- do_scan <-- ns_interfacemgr_scan0 <-- ns_interfacemgr_scan <-- scan_interfaces <--load_configuration <-- run_server <-- ns_server_create <-- setup <-- main

 其中ns_interface_listenudp的作用是在给定的IP地址和端口上监听UDP事件:

 首先,调用dns_dispatch_getudp()从interface manager中获取到udpdispatch(如果没有,就创建一个),其中在创建udpdispatch的dispatch_createudp函数中:
   a, 会调用get_udpsocket()创建新的isc_socket_t对象。get_udpsocket()中关键的是open_socket(sockmgr, localaddr,ISC_SOCKET_REUSEADDRESS, &sock)函数,它创建一个socket,并调用bind绑定IP地址和端口。关键步骤是:
 
1
2
3
4
1),调用socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);创建socket.
2),调用 flags = fcntl(fd, F_GETFL, 0); flags |= PORT_NONBLOCK;  ret = fcntl(fd, F_SETFL, flags);将socket设置为非阻塞模式
3),调用setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on))设置套接字选项
4),调用bind(sock->fd, &sockaddr->type.sa, sockaddr->length) 为该socket绑定IP地址和端口
 
    b, socket创建好,bind好之后。分配64个task(这些task存在dispatch->task[64]数组中),然后为dispatch->ctlevent分配事件,它调用distroy_disp来销毁一个dispatch(当然其中会调用closesocket来关闭一个socket).
 
  2,通过getudp获取到udpdispatch之后,就调用ns_clientmgr_createclients(ifp->clientmgr, ns_g_cpus, ifp, ISC_FALSE);来创建线程监听这个interface ifp了:
      创建ns_g_cpu个client,然后调用ev = &client->ctlevent;  isc_task_send(client->task, &ev);开始干client_start活
     其中创建client的时候,client->sendevent干client_senddone活;  client->recvevent干client_request活; client->ctlevent干client_start活
 
3, client_start
       对于UDP,执行client_udprecv()函数,client_udprecv的核心是执行isc_socket_recv2函数,isc_socket_recv2的核心是执行socket_recv();socket_recv的核心是doio_recv()

 

工作线程

  上面的isc_task_send(client->task, &ev)被调用后,主进程就把任务丢给了工作线程去做。

BIND9中的UDP数据处理,布布扣,bubuko.com

BIND9中的UDP数据处理

原文:http://www.cnblogs.com/cobbliu/p/3590685.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!