bind udp 处理流程之补充篇

来源:互联网 发布:无线端淘宝卖家运营 编辑:程序博客网 时间:2024/06/01 09:09

概述

udp数据的处理主要的处理流程已经在http://blog.csdn.net/divlee130/article/details/46391981有所介绍,但是具体到当一个请求过来时是如何提取请求信息,然后根据请求如果处理下一步的操作等等。 这些到目前为止还不清楚。本文试图解决这个问题。本文的分析是基于client请求A记录且没有缓存的情况。

前言

主流程中epoll 监听socket事件,如有事件则处理相关的句柄,即相关的socket,fd句柄都是通过socket manager来管理的,如果是写socket 并且不是侦听者则进入dispatch_recve进行接收任务分发,这个过程是通过 isc_task_send来完成的。通过事件的type和action 最终确定任务的回调处理是client_request

client_request

通过创建client_create注册ISC_SOCKEVENT_RECVDONE事件,当有dns请求时会执行client_request回调处理相应的数据。

    client->recvevent = (isc_socketevent_t *)                           isc_event_allocate(client->mctx, client,                           ISC_SOCKEVENT_RECVDONE,                           client_request, client,                           sizeof(isc_socketevent_t));

从主进程创建interface并监听UDPsocket到client_create
这里写图片描述

client_request处理是请求入口。比较复杂。这里只列出主要的过程。
client_request 主要做了以下几个事。

  1. 取socket buf。
  2. 检查请求信息合法性,如果请求非法退出。
  3. 解析消息,如果消息非法则退出。
  4. edns client-subnet 处理。获取client_ip。
  5. 找view的配置以匹配源IP。
  6. check signature。
  7. 分发请求。ns_query_start

ns_query_start

主要干的事

  1. 查看client cache是否存在,如果没有相应的cahce清除相应的标志位。
  2. 查看是否可以递归,如果RD flags==0则清除相应的递归标志位。
  3. 获取请求的question。
  4. DNS消息回复处理。
  5. 请求处理,query_find。

详细的流程如下。
这里写图片描述

query_find

处理查询。

以www.baidu.com为例。如为第一次请求。处理的大致流程为:
1. 查找相应的请求信息的cache,相应的处理函数为query_getdb
2. 如果没有命中走递归流程,相应的处理函数query_recurse
3. client_manager创建client,相应的处理函数ns_clientmgr_createclients
3. 创建www.baidu.com A的fetch信息相应的接口为dns_resolver_createfetch2
4. 创建www.baidu.com/A相应的fctx
5. 将www.baidu.com/A fctx加入任务队列
6. fctx回调处理

这里写图片描述

请求的流程

1.dispatch_recv收到报文请求事件。来自client的请求。然后加相应的任务队列。
2.任务队列收到event事件。等待调度。
3调度开始,处理消息。主要是根据cmsg。
4.根据请求的view来处理根据信息baidu.com/A/IN查询是否曾经缓存过。
5.没有缓存过创建client_mgr,并创建featch,通过fctx完成递归的工作,
通过getaddresss取得去哪查询,如果是第一次将用本地保存的.文件去递归查询。
6.同时named还有一个操作去根同步本地的地址信息。这个不是主要流程。但是每次抓包都可以看个2个报文是做这个的。
7.fctx通过resquery来发送相应的请求,向根发送baidu.com/A的请求。
8.如果根回复了bind,则通过再次触发dispatch_recv,最终依然走到client_request流程。根据报文头QR标记确定是个回应报文走UDP_RECV的流程。通过DNS_ID和地址来判断是否匹配上个请求信息。根据回报文确定是否需要回复client。
9.如果不是最终的结果则首先answer_response,缓存上次查询的内容,继续递归。这回的目标地址是上次回复消息中的地址。
10.重复上述的流程。直到最终获取到结果。

1 0
原创粉丝点击